text:
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------

namespace System.Activities.Tracking
{
    using System;
    using System.Activities;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Runtime;
    using System.Runtime.Diagnostics;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Text;
    using System.Runtime.Serialization;
    using System.Security;
    using System.Security.Permissions;
    using System.Diagnostics.CodeAnalysis;
    using System.Xml;

    public sealed class EtwTrackingParticipant : TrackingParticipant
    {
        const string truncatedItemsTag = "<items>...</items>";
        const string emptyItemsTag = "<items />";
        const string itemsTag = "items";
        const string itemTag = "item";
        const string nameAttribute = "name";
        const string typeAttribute = "type";

        static Hashtable diagnosticTraceCache = new Hashtable();
        NetDataContractSerializer variableSerializer;
        EtwDiagnosticTrace diagnosticTrace;
        Guid etwProviderId;

        // This constructor requires UnmanagedCode permission. It is demanded in InitializeEtwTrackingProvider, which
        // is called from set_EtwProviderId, which this calls.
        public EtwTrackingParticipant()
        {
            if (EtwDiagnosticTrace.DefaultEtwProviderId == Guid.Empty)
            {
                this.EtwProviderId = EtwDiagnosticTrace.ImmutableDefaultEtwProviderId;
            }
            else
            {
                this.EtwProviderId = EtwDiagnosticTrace.DefaultEtwProviderId;
            }
            this.ApplicationReference = string.Empty;
        }

        [Fx.Tag.KnownXamlExternal]
        public Guid EtwProviderId
        {
            get
            {
                return this.etwProviderId;
            }
            // This requires UnmanagedCode permission. It is demanded in InitializeEtwTrackingProvider.
            set
            {
                if (value == Guid.Empty)
                {
                    throw FxTrace.Exception.ArgumentNullOrEmpty("value");
                }
                InitializeEtwTrackingProvider(value);
            }
        }

        public string ApplicationReference
        {
            get;

            set;
        }

        protected internal override IAsyncResult BeginTrack(TrackingRecord record, TimeSpan timeout, AsyncCallback callback, object state)
        {
            Track(record, timeout);
            return new CompletedAsyncResult(callback, state);
        }

        protected internal override void EndTrack(IAsyncResult result)
        {
            CompletedAsyncResult.End(result);
        }

        protected internal override void Track(TrackingRecord record, TimeSpan timeout)
        {
            if (this.diagnosticTrace.IsEtwProviderEnabled)
            {
                if (record is ActivityStateRecord)
                {
                    TrackActivityRecord((ActivityStateRecord)record);
                }
                else if (record is WorkflowInstanceRecord)
                {
                    TrackWorkflowRecord((WorkflowInstanceRecord)record);
                }
                else if (record is BookmarkResumptionRecord)
                {
                    TrackBookmarkRecord((BookmarkResumptionRecord)record);
                }
                else if (record is ActivityScheduledRecord)
                {
                    TrackActivityScheduledRecord((ActivityScheduledRecord)record);
                }
                else if (record is CancelRequestedRecord)
                {
                    TrackCancelRequestedRecord((CancelRequestedRecord)record);
                }
                else if (record is FaultPropagationRecord)
                {
                    TrackFaultPropagationRecord((FaultPropagationRecord)record);
                }
                else
                {
                    Fx.Assert(record is CustomTrackingRecord, "Expected only CustomTrackingRecord");
                    TrackCustomRecord((CustomTrackingRecord)record);
                }
            }
        }

        [Fx.Tag.SecurityNote(Critical = "Calls EtwDiagonsticTrace.ctor with a provider id, which is SecurityCritical",
            Safe = "We demand UnmanagedCode.")]
        [SecuritySafeCritical]
        [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
        void InitializeEtwTrackingProvider(Guid providerId)
        {
            this.diagnosticTrace = (EtwDiagnosticTrace)diagnosticTraceCache[providerId];
            if (this.diagnosticTrace == null)
            {
                lock (diagnosticTraceCache)
                {
                    this.diagnosticTrace = (EtwDiagnosticTrace)diagnosticTraceCache[providerId];
                    if (this.diagnosticTrace == null)
                    {
                        this.diagnosticTrace = new EtwDiagnosticTrace(null, providerId);
                        diagnosticTraceCache.Add(providerId, this.diagnosticTrace);
                    }
                }
            }

            this.etwProviderId = providerId;
        }

        string PrepareDictionary(IDictionary<string, object> data)
        {
            StringBuilder builder = new StringBuilder();
            XmlWriterSettings settings = new XmlWriterSettings()
            {
                OmitXmlDeclaration = true
            };
            using (XmlWriter writer = XmlWriter.Create(builder, settings))
            {
                writer.WriteStartElement(itemsTag);

                if (data != null)
                {
                    foreach (KeyValuePair<string, object> item in data)
                    {
                        writer.WriteStartElement(itemTag);
                        writer.WriteAttributeString(nameAttribute, item.Key);
                        if (item.Value == null)
                        {
                            writer.WriteAttributeString(typeAttribute, string.Empty);
                            writer.WriteValue(string.Empty);
                        }
                        else
                        {
                            Type valueType = item.Value.GetType();
                            writer.WriteAttributeString(typeAttribute, valueType.FullName);

                            if (valueType == typeof(int) || valueType == typeof(float) || valueType == typeof(double) ||
                                valueType == typeof(long) || valueType == typeof(bool) || valueType == typeof(uint) ||
                                valueType == typeof(ushort) || valueType == typeof(short) || valueType == typeof(ulong) ||
                                valueType == typeof(string) || valueType == typeof(DateTimeOffset))
                            {
                                writer.WriteValue(item.Value);
                            }
                            else if (valueType == typeof(Guid))
                            {
                                Guid value = (Guid)item.Value;
                                writer.WriteValue(value.ToString());
                            }
                            else if (valueType == typeof(DateTime))
                            {
                                DateTime date = ((DateTime)item.Value).ToUniversalTime();
                                writer.WriteValue(date);
                            }
                            else
                            {
                                if (this.variableSerializer == null)
                                {
                                    this.variableSerializer = new NetDataContractSerializer();
                                }

                                try
                                {
                                    this.variableSerializer.WriteObject(writer, item.Value);
                                }
                                catch (Exception e)
                                {
                                    if (Fx.IsFatal(e))
                                    {
                                        throw;
                                    }
                                    TraceItemNotSerializable(item.Key, e);
                                }
                            }
                        }
                        writer.WriteEndElement();
                    }
                }
                writer.WriteEndElement();
                writer.Flush();
                return builder.ToString();
            }
        }

        static string PrepareAnnotations(IDictionary<string, string> data)
        {
            string stringTypeName = typeof(string).FullName;

            StringBuilder builder = new StringBuilder();
            XmlWriterSettings settings = new XmlWriterSettings()
            {
                OmitXmlDeclaration = true
            };
            using (XmlWriter writer = XmlWriter.Create(builder, settings))
            {
                writer.WriteStartElement(itemsTag);

                if (data != null)
                {
                    foreach (KeyValuePair<string, string> item in data)
                    {
                        writer.WriteStartElement(itemTag);
                        writer.WriteAttributeString(nameAttribute, item.Key);
                        writer.WriteAttributeString(typeAttribute, stringTypeName);
                        if (item.Value == null)
                        {
                            writer.WriteValue(string.Empty);
                        }
                        else
                        {
                            writer.WriteValue(item.Value);
                        }
                        writer.WriteEndElement();
                    }
                }
                writer.WriteEndElement();
                writer.Flush();
                return builder.ToString();
            }
        }

        static void TraceItemNotSerializable(string item, Exception e)
        {
            //trace the exception.
            FxTrace.Exception.AsInformation(e);

            if (TD.TrackingValueNotSerializableIsEnabled())
            {
                TD.TrackingValueNotSerializable(item);
            }
        }

        void TraceTrackingRecordDropped(long recordNumber)
        {
            if (TD.TrackingRecordDroppedIsEnabled())
            {
                TD.TrackingRecordDropped(recordNumber, this.EtwProviderId);
            }
        }

        void TraceTrackingRecordTruncated(long recordNumber)
        {
            if (TD.TrackingRecordTruncatedIsEnabled())
            {
                TD.TrackingRecordTruncated(recordNumber, this.EtwProviderId);
            }
        }

        void TrackActivityRecord(ActivityStateRecord record)
        {
            if (EtwTrackingParticipantTrackRecords.ActivityStateRecordIsEnabled(this.diagnosticTrace))
            {
                if (!EtwTrackingParticipantTrackRecords.ActivityStateRecord(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                    record.RecordNumber, record.EventTime.ToFileTime(), record.State,
                    record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName,
                    record.Arguments.Count > 0 ? PrepareDictionary(record.Arguments) : emptyItemsTag,
                    record.Variables.Count > 0 ? PrepareDictionary(record.Variables) : emptyItemsTag,
                    record.HasAnnotations ? PrepareAnnotations(record.Annotations) : emptyItemsTag,
                    this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                {
                    if (EtwTrackingParticipantTrackRecords.ActivityStateRecord(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                        record.RecordNumber, record.EventTime.ToFileTime(), record.State,
                        record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName, truncatedItemsTag, truncatedItemsTag,
                        truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        TraceTrackingRecordTruncated(record.RecordNumber);
                    }
                    else
                    {
                        TraceTrackingRecordDropped(record.RecordNumber);
                    }
                }
            }
        }

        void TrackActivityScheduledRecord(ActivityScheduledRecord scheduledRecord)
        {
            if (EtwTrackingParticipantTrackRecords.ActivityScheduledRecordIsEnabled(this.diagnosticTrace))
            {
                if (!EtwTrackingParticipantTrackRecords.ActivityScheduledRecord(this.diagnosticTrace, scheduledRecord.EventTraceActivity, scheduledRecord.InstanceId,
                    scheduledRecord.RecordNumber,
                    scheduledRecord.EventTime.ToFileTime(),
                    scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.Name,
                    scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.Id,
                    scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.InstanceId,
                    scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.TypeName,
                    scheduledRecord.Child.Name, scheduledRecord.Child.Id, scheduledRecord.Child.InstanceId, scheduledRecord.Child.TypeName,
                    scheduledRecord.HasAnnotations ? PrepareAnnotations(scheduledRecord.Annotations) : emptyItemsTag,
                    this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                {
                    if (EtwTrackingParticipantTrackRecords.ActivityScheduledRecord(this.diagnosticTrace, scheduledRecord.EventTraceActivity, scheduledRecord.InstanceId,
                        scheduledRecord.RecordNumber,
                        scheduledRecord.EventTime.ToFileTime(),
                        scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.Name,
                        scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.Id,
                        scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.InstanceId,
                        scheduledRecord.Activity == null ? string.Empty : scheduledRecord.Activity.TypeName,
                        scheduledRecord.Child.Name, scheduledRecord.Child.Id, scheduledRecord.Child.InstanceId, scheduledRecord.Child.TypeName,
                        truncatedItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        TraceTrackingRecordTruncated(scheduledRecord.RecordNumber);
                    }
                    else
                    {
                        TraceTrackingRecordDropped(scheduledRecord.RecordNumber);
                    }
                }
            }
        }

        void TrackCancelRequestedRecord(CancelRequestedRecord cancelRecord)
        {
            if (EtwTrackingParticipantTrackRecords.CancelRequestedRecordIsEnabled(this.diagnosticTrace))
            {
                if (!EtwTrackingParticipantTrackRecords.CancelRequestedRecord(this.diagnosticTrace, cancelRecord.EventTraceActivity, cancelRecord.InstanceId,
                    cancelRecord.RecordNumber,
                    cancelRecord.EventTime.ToFileTime(),
                    cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.Name,
                    cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.Id,
                    cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.InstanceId,
                    cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.TypeName,
                    cancelRecord.Child.Name, cancelRecord.Child.Id, cancelRecord.Child.InstanceId, cancelRecord.Child.TypeName,
                    cancelRecord.HasAnnotations ? PrepareAnnotations(cancelRecord.Annotations) : emptyItemsTag,
                    this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                {
                    if (EtwTrackingParticipantTrackRecords.CancelRequestedRecord(this.diagnosticTrace, cancelRecord.EventTraceActivity, cancelRecord.InstanceId,
                        cancelRecord.RecordNumber,
                        cancelRecord.EventTime.ToFileTime(),
                        cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.Name,
                        cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.Id,
                        cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.InstanceId,
                        cancelRecord.Activity == null ? string.Empty : cancelRecord.Activity.TypeName,
                        cancelRecord.Child.Name, cancelRecord.Child.Id, cancelRecord.Child.InstanceId, cancelRecord.Child.TypeName,
                        truncatedItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        TraceTrackingRecordTruncated(cancelRecord.RecordNumber);
                    }
                    else
                    {
                        TraceTrackingRecordDropped(cancelRecord.RecordNumber);
                    }
                }
            }
        }

        void TrackFaultPropagationRecord(FaultPropagationRecord faultRecord)
        {
            if (EtwTrackingParticipantTrackRecords.FaultPropagationRecordIsEnabled(this.diagnosticTrace))
            {
                if (!EtwTrackingParticipantTrackRecords.FaultPropagationRecord(this.diagnosticTrace, faultRecord.EventTraceActivity, faultRecord.InstanceId,
                    faultRecord.RecordNumber,
                    faultRecord.EventTime.ToFileTime(),
                    faultRecord.FaultSource.Name, faultRecord.FaultSource.Id, faultRecord.FaultSource.InstanceId, faultRecord.FaultSource.TypeName,
                    faultRecord.FaultHandler != null ? faultRecord.FaultHandler.Name : string.Empty,
                    faultRecord.FaultHandler != null ? faultRecord.FaultHandler.Id : string.Empty,
                    faultRecord.FaultHandler != null ? faultRecord.FaultHandler.InstanceId : string.Empty,
                    faultRecord.FaultHandler != null ? faultRecord.FaultHandler.TypeName : string.Empty,
                    faultRecord.Fault.ToString(), faultRecord.IsFaultSource,
                    faultRecord.HasAnnotations ? PrepareAnnotations(faultRecord.Annotations) : emptyItemsTag,
                    this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                {
                    if (EtwTrackingParticipantTrackRecords.FaultPropagationRecord(this.diagnosticTrace, faultRecord.EventTraceActivity, faultRecord.InstanceId,
                        faultRecord.RecordNumber,
                        faultRecord.EventTime.ToFileTime(),
                        faultRecord.FaultSource.Name, faultRecord.FaultSource.Id, faultRecord.FaultSource.InstanceId, faultRecord.FaultSource.TypeName,
                        faultRecord.FaultHandler != null ? faultRecord.FaultHandler.Name : string.Empty,
                        faultRecord.FaultHandler != null ? faultRecord.FaultHandler.Id : string.Empty,
                        faultRecord.FaultHandler != null ? faultRecord.FaultHandler.InstanceId : string.Empty,
                        faultRecord.FaultHandler != null ? faultRecord.FaultHandler.TypeName : string.Empty,
                        faultRecord.Fault.ToString(), faultRecord.IsFaultSource,
                        truncatedItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        TraceTrackingRecordTruncated(faultRecord.RecordNumber);
                    }
                    else
                    {
                        TraceTrackingRecordDropped(faultRecord.RecordNumber);
                    }
                }
            }
        }

        void TrackBookmarkRecord(BookmarkResumptionRecord record)
        {
            if (EtwTrackingParticipantTrackRecords.BookmarkResumptionRecordIsEnabled(this.diagnosticTrace))
            {
                if (!EtwTrackingParticipantTrackRecords.BookmarkResumptionRecord(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId, record.RecordNumber, record.EventTime.ToFileTime(),
                    record.BookmarkName, record.BookmarkScope, record.Owner.Name, record.Owner.Id,
                    record.Owner.InstanceId, record.Owner.TypeName,
                    record.HasAnnotations ? PrepareAnnotations(record.Annotations) : emptyItemsTag,
                    this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                {
                    if (EtwTrackingParticipantTrackRecords.BookmarkResumptionRecord(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId, record.RecordNumber, record.EventTime.ToFileTime(),
                        record.BookmarkName, record.BookmarkScope, record.Owner.Name, record.Owner.Id,
                        record.Owner.InstanceId, record.Owner.TypeName,
                        truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        TraceTrackingRecordTruncated(record.RecordNumber);
                    }
                    else
                    {
                        TraceTrackingRecordDropped(record.RecordNumber);
                    }
                }
            }
        }

        void TrackCustomRecord(CustomTrackingRecord record)
        {
            switch (record.Level)
            {
                case TraceLevel.Error:
                    if (EtwTrackingParticipantTrackRecords.CustomTrackingRecordErrorIsEnabled(this.diagnosticTrace))
                    {
                        if (!EtwTrackingParticipantTrackRecords.CustomTrackingRecordError(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                                            record.RecordNumber, record.EventTime.ToFileTime(), record.Name,
                                            record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName,
                                            PrepareDictionary(record.Data),
                                            record.HasAnnotations ? PrepareAnnotations(record.Annotations) : emptyItemsTag,
                                            this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            if (EtwTrackingParticipantTrackRecords.CustomTrackingRecordError(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                                record.RecordNumber, record.EventTime.ToFileTime(), record.Name,
                                record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName,
                                truncatedItemsTag, truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                            {
                                TraceTrackingRecordTruncated(record.RecordNumber);
                            }
                            else
                            {
                                TraceTrackingRecordDropped(record.RecordNumber);
                            }
                        }
                    }
                    break;
                case TraceLevel.Warning:
                    if (EtwTrackingParticipantTrackRecords.CustomTrackingRecordWarningIsEnabled(this.diagnosticTrace))
                    {
                        if (!EtwTrackingParticipantTrackRecords.CustomTrackingRecordWarning(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                                             record.RecordNumber, record.EventTime.ToFileTime(), record.Name,
                                             record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName,
                                             PrepareDictionary(record.Data),
                                             record.HasAnnotations ? PrepareAnnotations(record.Annotations) : emptyItemsTag,
                                             this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            if (EtwTrackingParticipantTrackRecords.CustomTrackingRecordWarning(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                                record.RecordNumber, record.EventTime.ToFileTime(), record.Name,
                                record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName,
                                truncatedItemsTag, truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                            {
                                TraceTrackingRecordTruncated(record.RecordNumber);
                            }
                            else
                            {
                                TraceTrackingRecordDropped(record.RecordNumber);
                            }
                        }
                    }
                    break;

                default:
                    if (EtwTrackingParticipantTrackRecords.CustomTrackingRecordInfoIsEnabled(this.diagnosticTrace))
                    {
                        if (!EtwTrackingParticipantTrackRecords.CustomTrackingRecordInfo(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                                        record.RecordNumber, record.EventTime.ToFileTime(), record.Name,
                                             record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName,
                                        PrepareDictionary(record.Data),
                                        record.HasAnnotations ? PrepareAnnotations(record.Annotations) : emptyItemsTag,
                                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            if (EtwTrackingParticipantTrackRecords.CustomTrackingRecordInfo(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId,
                                record.RecordNumber, record.EventTime.ToFileTime(), record.Name,
                                record.Activity.Name, record.Activity.Id, record.Activity.InstanceId, record.Activity.TypeName,
                                truncatedItemsTag, truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                            {
                                TraceTrackingRecordTruncated(record.RecordNumber);
                            }
                            else
                            {
                                TraceTrackingRecordDropped(record.RecordNumber);
                            }
                        }
                    }
                    break;
            }
        }

        void TrackWorkflowRecord(WorkflowInstanceRecord record)
        {
            // In the TrackWorkflowInstance*Record methods below there are two code paths.
            // If the WorkflowIdentity is null, then we follow the exisiting 4.0 path.
            // If the WorkflowIdentity is provided, then if a particular field in the workflowInstance
            // record is null, we need to ensure that we are passing string.Empty.
            // The WriteEvent method on the DiagnosticEventProvider which is called in the
            // WriteEtwEvent in the EtwTrackingParticipantRecords class invokes the EventWrite
            // native method which relies on getting the record arguments in a particular order.
            if (record is WorkflowInstanceUnhandledExceptionRecord)
            {
                TrackWorkflowInstanceUnhandledExceptionRecord(record);
            }
            else if (record is WorkflowInstanceAbortedRecord)
            {
                TrackWorkflowInstanceAbortedRecord(record);
            }
            else if (record is WorkflowInstanceSuspendedRecord)
            {
                TrackWorkflowInstanceSuspendedRecord(record);
            }
            else if (record is WorkflowInstanceTerminatedRecord)
            {
                TrackWorkflowInstanceTerminatedRecord(record);
            }
            else if (record is WorkflowInstanceUpdatedRecord)
            {
                TrackWorkflowInstanceUpdatedRecord(record);
            }
            else
            {
                TrackWorkflowInstanceRecord(record);
            }
        }

        void TrackWorkflowInstanceUnhandledExceptionRecord(WorkflowInstanceRecord record)
        {
            WorkflowInstanceUnhandledExceptionRecord unhandled = record as WorkflowInstanceUnhandledExceptionRecord;
            if (unhandled.WorkflowDefinitionIdentity == null)
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceUnhandledExceptionRecordIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceUnhandledExceptionRecord(this.diagnosticTrace, unhandled.EventTraceActivity, unhandled.InstanceId,
                        unhandled.RecordNumber, unhandled.EventTime.ToFileTime(), unhandled.ActivityDefinitionId,
                        unhandled.FaultSource.Name, unhandled.FaultSource.Id, unhandled.FaultSource.InstanceId, unhandled.FaultSource.TypeName,
                        unhandled.UnhandledException == null ? string.Empty : unhandled.UnhandledException.ToString(),
                        unhandled.HasAnnotations ? PrepareAnnotations(unhandled.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceUnhandledExceptionRecord(this.diagnosticTrace, unhandled.EventTraceActivity, unhandled.InstanceId,
                            unhandled.RecordNumber, unhandled.EventTime.ToFileTime(), unhandled.ActivityDefinitionId,
                            unhandled.FaultSource.Name, unhandled.FaultSource.Id, unhandled.FaultSource.InstanceId, unhandled.FaultSource.TypeName,
                            unhandled.UnhandledException == null ? string.Empty : unhandled.UnhandledException.ToString(),
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(unhandled.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(unhandled.RecordNumber);
                        }
                    }
                }
            }
            else
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceUnhandledExceptionRecordWithIdIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceUnhandledExceptionRecordWithId(this.diagnosticTrace, unhandled.EventTraceActivity, unhandled.InstanceId,
                        unhandled.RecordNumber, unhandled.EventTime.ToFileTime(), unhandled.ActivityDefinitionId,
                        unhandled.FaultSource.Name, unhandled.FaultSource.Id, unhandled.FaultSource.InstanceId, unhandled.FaultSource.TypeName,
                        unhandled.UnhandledException == null ? string.Empty : unhandled.UnhandledException.ToString(),
                        unhandled.HasAnnotations ? PrepareAnnotations(unhandled.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                        unhandled.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceUnhandledExceptionRecordWithId(this.diagnosticTrace, unhandled.EventTraceActivity, unhandled.InstanceId,
                            unhandled.RecordNumber, unhandled.EventTime.ToFileTime(), unhandled.ActivityDefinitionId,
                            unhandled.FaultSource.Name, unhandled.FaultSource.Id, unhandled.FaultSource.InstanceId, unhandled.FaultSource.TypeName,
                            unhandled.UnhandledException == null ? string.Empty : unhandled.UnhandledException.ToString(),
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                            unhandled.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(unhandled.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(unhandled.RecordNumber);
                        }
                    }
                }
            }
        }

        void TrackWorkflowInstanceAbortedRecord(WorkflowInstanceRecord record)
        {
            WorkflowInstanceAbortedRecord aborted = record as WorkflowInstanceAbortedRecord;
            if (aborted.WorkflowDefinitionIdentity == null)
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceAbortedRecordIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceAbortedRecord(this.diagnosticTrace, aborted.EventTraceActivity, aborted.InstanceId, aborted.RecordNumber,
                        aborted.EventTime.ToFileTime(), aborted.ActivityDefinitionId, aborted.Reason,
                        aborted.HasAnnotations ? PrepareAnnotations(aborted.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceAbortedRecord(this.diagnosticTrace, aborted.EventTraceActivity, aborted.InstanceId, aborted.RecordNumber,
                            aborted.EventTime.ToFileTime(), aborted.ActivityDefinitionId, aborted.Reason,
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(aborted.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(aborted.RecordNumber);
                        }
                    }
                }
            }
            else
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceAbortedRecordWithIdIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceAbortedRecordWithId(this.diagnosticTrace, aborted.EventTraceActivity, aborted.InstanceId, aborted.RecordNumber,
                        aborted.EventTime.ToFileTime(), aborted.ActivityDefinitionId, aborted.Reason,
                        aborted.HasAnnotations ? PrepareAnnotations(aborted.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                        aborted.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceAbortedRecordWithId(this.diagnosticTrace, aborted.EventTraceActivity, aborted.InstanceId, aborted.RecordNumber,
                            aborted.EventTime.ToFileTime(), aborted.ActivityDefinitionId, aborted.Reason,
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                            aborted.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(aborted.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(aborted.RecordNumber);
                        }
                    }
                }
            }
        }

        void TrackWorkflowInstanceSuspendedRecord(WorkflowInstanceRecord record)
        {
            WorkflowInstanceSuspendedRecord suspended = record as WorkflowInstanceSuspendedRecord;
            if (suspended.WorkflowDefinitionIdentity == null)
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceSuspendedRecordIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceSuspendedRecord(this.diagnosticTrace, suspended.EventTraceActivity, suspended.InstanceId, suspended.RecordNumber,
                        suspended.EventTime.ToFileTime(), suspended.ActivityDefinitionId, suspended.Reason,
                        suspended.HasAnnotations ? PrepareAnnotations(suspended.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceSuspendedRecord(this.diagnosticTrace, suspended.EventTraceActivity, suspended.InstanceId, suspended.RecordNumber,
                            suspended.EventTime.ToFileTime(), suspended.ActivityDefinitionId, suspended.Reason,
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(suspended.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(suspended.RecordNumber);
                        }
                    }
                }
            }
            else
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceSuspendedRecordWithIdIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceSuspendedRecordWithId(this.diagnosticTrace, suspended.EventTraceActivity, suspended.InstanceId, suspended.RecordNumber,
                        suspended.EventTime.ToFileTime(), suspended.ActivityDefinitionId, suspended.Reason,
                        suspended.HasAnnotations ? PrepareAnnotations(suspended.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                        suspended.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceSuspendedRecordWithId(this.diagnosticTrace, suspended.EventTraceActivity, suspended.InstanceId, suspended.RecordNumber,
                            suspended.EventTime.ToFileTime(), suspended.ActivityDefinitionId, suspended.Reason,
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                            suspended.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(suspended.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(suspended.RecordNumber);
                        }
                    }
                }
            }
        }

        void TrackWorkflowInstanceTerminatedRecord(WorkflowInstanceRecord record)
        {
            WorkflowInstanceTerminatedRecord terminated = record as WorkflowInstanceTerminatedRecord;
            if (terminated.WorkflowDefinitionIdentity == null)
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceTerminatedRecordIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceTerminatedRecord(this.diagnosticTrace, terminated.EventTraceActivity, terminated.InstanceId, terminated.RecordNumber,
                        terminated.EventTime.ToFileTime(), terminated.ActivityDefinitionId, terminated.Reason,
                        terminated.HasAnnotations ? PrepareAnnotations(terminated.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceTerminatedRecord(this.diagnosticTrace, terminated.EventTraceActivity, terminated.InstanceId, terminated.RecordNumber,
                            terminated.EventTime.ToFileTime(), terminated.ActivityDefinitionId, terminated.Reason,
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(terminated.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(terminated.RecordNumber);
                        }
                    }
                }
            }
            else
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceTerminatedRecordWithIdIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceTerminatedRecordWithId(this.diagnosticTrace, terminated.EventTraceActivity, terminated.InstanceId, terminated.RecordNumber,
                        terminated.EventTime.ToFileTime(), terminated.ActivityDefinitionId, terminated.Reason,
                        terminated.HasAnnotations ? PrepareAnnotations(terminated.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                        terminated.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceTerminatedRecordWithId(this.diagnosticTrace, terminated.EventTraceActivity, terminated.InstanceId, terminated.RecordNumber,
                            terminated.EventTime.ToFileTime(), terminated.ActivityDefinitionId, terminated.Reason,
                            truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                            terminated.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(terminated.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(terminated.RecordNumber);
                        }
                    }
                }
            }
        }

        void TrackWorkflowInstanceRecord(WorkflowInstanceRecord record)
        {
            if (record.WorkflowDefinitionIdentity == null)
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceRecordIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceRecord(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId, record.RecordNumber,
                        record.EventTime.ToFileTime(), record.ActivityDefinitionId,
                        record.State,
                        record.HasAnnotations ? PrepareAnnotations(record.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceRecord(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId, record.RecordNumber, record.EventTime.ToFileTime(),
                            record.ActivityDefinitionId, record.State, truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(record.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(record.RecordNumber);
                        }
                    }
                }
            }
            else
            {
                if (EtwTrackingParticipantTrackRecords.WorkflowInstanceRecordWithIdIsEnabled(this.diagnosticTrace))
                {
                    if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceRecordWithId(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId, record.RecordNumber,
                        record.EventTime.ToFileTime(), record.ActivityDefinitionId,
                        record.State,
                        record.HasAnnotations ? PrepareAnnotations(record.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                        record.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                    {
                        if (EtwTrackingParticipantTrackRecords.WorkflowInstanceRecordWithId(this.diagnosticTrace, record.EventTraceActivity, record.InstanceId, record.RecordNumber, record.EventTime.ToFileTime(),
                            record.ActivityDefinitionId, record.State, truncatedItemsTag, this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name,
                            record.WorkflowDefinitionIdentity.ToString(), this.ApplicationReference))
                        {
                            TraceTrackingRecordTruncated(record.RecordNumber);
                        }
                        else
                        {
                            TraceTrackingRecordDropped(record.RecordNumber);
                        }
                    }
                }
            }
        }

        void TrackWorkflowInstanceUpdatedRecord(WorkflowInstanceRecord record)
        {
            if (EtwTrackingParticipantTrackRecords.WorkflowInstanceUpdatedRecordIsEnabled(this.diagnosticTrace))
            {
                WorkflowInstanceUpdatedRecord updatedRecord = record as WorkflowInstanceUpdatedRecord;
                if (!EtwTrackingParticipantTrackRecords.WorkflowInstanceUpdatedRecord(this.diagnosticTrace, updatedRecord.EventTraceActivity, updatedRecord.InstanceId,
                    updatedRecord.RecordNumber, updatedRecord.EventTime.ToFileTime(), updatedRecord.ActivityDefinitionId, updatedRecord.State,
                    updatedRecord.OriginalDefinitionIdentity == null ? string.Empty : updatedRecord.OriginalDefinitionIdentity.ToString(),
                    updatedRecord.WorkflowDefinitionIdentity == null ? string.Empty : updatedRecord.WorkflowDefinitionIdentity.ToString(),
                    updatedRecord.HasAnnotations ? PrepareAnnotations(updatedRecord.Annotations) : emptyItemsTag,
                    this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                {
                    if (EtwTrackingParticipantTrackRecords.WorkflowInstanceUpdatedRecord(this.diagnosticTrace, updatedRecord.EventTraceActivity, updatedRecord.InstanceId,
                        updatedRecord.RecordNumber, updatedRecord.EventTime.ToFileTime(), updatedRecord.ActivityDefinitionId, updatedRecord.State,
                        updatedRecord.OriginalDefinitionIdentity == null ? string.Empty : updatedRecord.OriginalDefinitionIdentity.ToString(),
                        updatedRecord.WorkflowDefinitionIdentity == null ? string.Empty : updatedRecord.WorkflowDefinitionIdentity.ToString(),
                        updatedRecord.HasAnnotations ? PrepareAnnotations(updatedRecord.Annotations) : emptyItemsTag,
                        this.TrackingProfile == null ? string.Empty : this.TrackingProfile.Name == null ? string.Empty : this.TrackingProfile.Name, this.ApplicationReference))
                    {
                        TraceTrackingRecordTruncated(updatedRecord.RecordNumber);
                    }
                    else
                    {
                        TraceTrackingRecordDropped(updatedRecord.RecordNumber);
                    }
                }
            }
        }
    }
}


text:
#ifndef ZBE_CORE_EVENTS_GENERATORS_INPUTEVENTGENERATOR_H
#define ZBE_CORE_EVENTS_GENERATORS_INPUTEVENTGENERATOR_H

#include <cstdint>
#include <memory>
#include <string>
#include <list>
#include <vector>
#include <unordered_map>
#include <nlohmann/json.hpp>

#include "ZBE/core/io/InputBuffer.h"
#include "ZBE/core/io/InputTextBuffer.h"
#include "ZBE/core/io/InputStatus.h"
#include "ZBE/core/io/InputText.h"
#include "ZBE/core/tools/containers/RsrcStore.h"
#include "ZBE/core/system/SysTime.h"
#include "ZBE/core/events/handlers/TextHandler.h"
#include "ZBE/core/events/handlers/InputHandler.h"
#include "ZBE/core/events/EventStore.h"
#include "ZBE/core/events/InputEvent.h"
#include "ZBE/core/events/TextEvent.h"
#include "ZBE/core/daemons/Daemon.h"

#include "ZBE/core/system/system.h"

#include "ZBE/factories/Factory.h"

namespace zbe {

using HandlerList = std::list<std::shared_ptr<InputHandler> >;
using HandlerTicket = HandlerList::iterator;

class ZBEAPI InputStatusManager {
public:

  virtual ~InputStatusManager() {}

  /** \brief Generate events if the InputStatus match some condition.
   *  Implementation dependant.
   *  \param is InputStatus to check
   */
  virtual bool generate(const InputStatus& is) = 0;
protected:
  template <typename IteratorA, typename IteratorB, typename IteratorC>
  inline bool range_contains(IteratorA from, const IteratorB& end, const IteratorC& candidate) {
      while (from != end)
          if (&*from++ == &*candidate)
              return true;
      return false;
  }

  template <typename List, typename Iterator>
  inline bool list_contains(List& l, const Iterator& candidate) {
    return range_contains(l.begin(), l.end(), candidate);
  }

  struct Handlers {
    HandlerList active;
    HandlerList inactive;
  };

};

class ZBEAPI MappedInputStatusManager : public InputStatusManager {
public:

  MappedInputStatusManager() : eventId(), store(EventStore::getInstance()), handlers() {}
  MappedInputStatusManager(int eventId) : eventId(eventId), store(EventStore::getInstance()), handlers() {}
  virtual ~MappedInputStatusManager() = default;

  /** Add a handler to an input event.
   * \param id Id of the key
   * \param handler Handler to run when key pressed
   */
  inline HandlerTicket addHandler(uint32_t inputId, std::shared_ptr<InputHandler> handler) {
    ensureListExists(inputId);
    handlers[inputId].active.push_front(handler);
    return handlers[inputId].active.begin();
  }

  /** Remove a handler from an input event.
   * \param id Id of the key
   */
  inline void removeHandler(uint32_t inputId, HandlerTicket ticket) {
    if (list_contains(handlers[inputId].active, ticket)) {
      handlers[inputId].active.erase(ticket);
    } else if (list_contains(handlers[inputId].inactive, ticket)) {
      handlers[inputId].inactive.erase(ticket);
    } else {
      SysError::setError("ERROR: Handler cant be erased, handler not found (wrong key?).");
    }
  }

  /** Remove a handler from an input event.
   * \param id Id of the key
   */
  inline void disableHandler(uint32_t inputId, HandlerTicket ticket) {
    if (list_contains(handlers[inputId].active, ticket)) {
      handlers[inputId].active.splice(ticket, handlers[inputId].inactive);
    } else if (!list_contains(handlers[inputId].inactive, ticket)) {
      SysError::setError("ERROR: Handler cant be disabled, handler not found (wrong key?).");
    }
  }

  /** Remove a handler from an input event.
   * \param id Id of the key
   */
  inline void enableHandler(uint32_t inputId, HandlerTicket ticket) {
    if (list_contains(handlers[inputId].inactive, ticket)) {
      handlers[inputId].inactive.splice(ticket, handlers[inputId].active);
    } else if (!list_contains(handlers[inputId].active, ticket)) {
      SysError::setError("ERROR: Handler cant be enabled, handler not found (wrong key?).");
    }
  }

  /** Remove a handler from an input event.
   * \param id Id of the key
   */
  inline void moveHandler(uint32_t srcInputId, uint32_t dstInputId, HandlerTicket ticket) {
    if (list_contains(handlers[srcInputId].active, ticket)) {
      ensureListExists(dstInputId);
      handlers[srcInputId].active.splice(ticket, handlers[dstInputId].active);
    } else if (list_contains(handlers[srcInputId].inactive, ticket)) {
      ensureListExists(dstInputId);
      handlers[srcInputId].inactive.splice(ticket, handlers[dstInputId].inactive);
    } else {
      SysError::setError("ERROR: Handler cant be moved, handler not found (wrong key?).");
    }
  }

  bool generate(const InputStatus& is) {
    bool is_generated = false;
    auto hit = handlers.find(is.getId());
    if (hit != handlers.end() && !hit->second.active.empty()) {
        is_generated = true;
        for(auto& h : hit->second.active) {
          InputEvent* e = new InputEvent(eventId, is.getTime(), is.getId(), is.getStatus(), h.get()); // TODO repensar ese shared_ptr reconvertido a puntero
          store.storeEvent(e);
        }
    }
    return is_generated;
  }

  inline void setEventID(int eventId) {
    this->eventId = eventId;
  }

private:
  void ensureListExists(uint32_t inputId) {
    // TODO en c++20 sustituir por contains
    auto hit = handlers.find(inputId);
    if (hit == handlers.end()) {
      handlers[inputId] = Handlers{};
    }
  }

  uint64_t eventId;
  EventStore &store;
  std::unordered_map<uint32_t, Handlers> handlers;

};

class ZBEAPI AnyInputStatusManager : public InputStatusManager {
public:
  virtual ~AnyInputStatusManager() {}

  virtual bool generate(const InputStatus& is) = 0;

};

class ZBEAPI InputEventGeneratorFtry;

/** \brief This class ZBEAPI will search for input event occurred between two given times and send it to the EventStore.
 */
class ZBEAPI InputEventGenerator : virtual public Daemon {
  public:
    friend class InputEventGeneratorFtry;

    InputEventGenerator(const InputEventGenerator&) = delete;  //!< Deleted copy constructor.
    void operator=(const InputEventGenerator&) = delete;  //!< Deleted operator.

    /** \brief Default constructor.
     */
    InputEventGenerator(std::shared_ptr<InputBuffer> inputBuffer, std::shared_ptr<InputTextBuffer> inputTextBuffer = nullptr, int eventId = 0, std::shared_ptr<TextHandler> handler = nullptr, std::shared_ptr<ContextTime> contextTime = nullptr) : inputBuffer(inputBuffer), inputTextBuffer(inputTextBuffer), mism(eventId), eventId(eventId), store(EventStore::getInstance()), handler(handler), contextTime(contextTime) {}

    /** \brief Empty destructor.
     */
    ~InputEventGenerator() = default;

    //void addManager(std::shared_ptr<InputStatusManager> manager) {;}

    /** Will search for input events occurred between initTime and finalTime and send it to the EventStore.
     * \param initTime Time from which events are generated
     * \param endTime Time until the events are generated
     */
    void run();
    inline HandlerTicket addHandler(uint32_t inputId, std::shared_ptr<InputHandler> handler) {
      return mism.addHandler(inputId, handler);
    }

    /** Remove a handler from an input event.
     * \param id Id of the key
     */
    inline void removeHandler(uint32_t inputId, HandlerTicket ticket) {
      mism.removeHandler(inputId, ticket);
    }

    /** Remove a handler from an input event.
     * \param id Id of the key
     */
    inline void disableHandler(uint32_t inputId, HandlerTicket ticket) {
      mism.disableHandler(inputId, ticket);
    }

    /** Remove a handler from an input event.
     * \param id Id of the key
     */
    inline void enableHandler(uint32_t inputId, HandlerTicket ticket) {
      mism.enableHandler(inputId, ticket);
    }

    /** Remove a handler from an input event.
     * \param id Id of the key
     */
    inline void moveHandler(uint32_t srcInputId, uint32_t dstInputId, HandlerTicket ticket) {
      mism.moveHandler(srcInputId, dstInputId, ticket);
    }

    inline void setTextHandler(std::shared_ptr<TextHandler> handler) {
      using namespace std::string_literals;
      if(handler != nullptr) {
        SysError::setError("InputEventGenerator already has a handler"s);
      }
      this->handler = handler;
    }

    inline void removeTextHandler() {
      this->handler = nullptr;
    }

    // TODO: añadir AnyInputStatusManager para teclado, raton, mando.... con sus metodos como los anteriores sin el "inputId" ¿Quizás deviceId?

  private:

    InputEventGenerator() : inputBuffer(nullptr), inputTextBuffer(nullptr), mism(), eventId(), store(EventStore::getInstance()), handler(nullptr), contextTime(nullptr) {}

    inline void setEventID(int eventId) {
      this->eventId = eventId;
      mism.setEventID(eventId);
    }

    inline void setInputBuffer(std::shared_ptr<InputBuffer> inputBuffer) {
      this->inputBuffer = inputBuffer;
    }

    inline void setInputTextBuffer(std::shared_ptr<InputTextBuffer> inputTextBuffer) {
      this->inputTextBuffer = inputTextBuffer;
    }

    inline void setContextTime(std::shared_ptr<ContextTime> contextTime) {
      this->contextTime = contextTime;
    }

    std::shared_ptr<InputBuffer> inputBuffer;
    std::shared_ptr<InputTextBuffer> inputTextBuffer;
    MappedInputStatusManager mism;
    uint64_t eventId;
    EventStore &store;
    std::shared_ptr<TextHandler> handler;
    std::shared_ptr<ContextTime> contextTime;
};

class ZBEAPI InputEventGeneratorFtry : public Factory {
public:

  /** \brief Builds a InputEventGenerator.
   *  \param name Name for the created InputEventGenerator.
   *  \param cfgId InputEventGenerator's configuration id.
   */
  void create(std::string name, uint64_t cfgId);

  /** \brief Setup the desired tool. The tool will be complete after this step.
   *  \param name Name of the tool.
   *  \param cfgId Tool's configuration id.
   */
  void setup(std::string name, uint64_t cfgId);

private:
  RsrcDictionary<uint64_t>& uintStore = RsrcDictionary<uint64_t>::getInstance();
  RsrcStore<nlohmann::json>& configRsrc = RsrcStore<nlohmann::json>::getInstance();
  RsrcStore<Daemon>& daemonRsrc = RsrcStore<Daemon>::getInstance();
  RsrcStore<InputEventGenerator>& iegRsrc = RsrcStore<InputEventGenerator>::getInstance();
  RsrcStore<ContextTime>& cTimeRsrc = RsrcStore<ContextTime>::getInstance();
  RsrcStore<InputBuffer>& ibuffRsrc = RsrcStore<InputBuffer>::getInstance();
  RsrcStore<InputTextBuffer>& itBuffRsrc = RsrcStore<InputTextBuffer>::getInstance();

};

}  // namespace zbe

#endif  // ZBE_CORE_EVENTS_GENERATORS_INPUTEVENTGENERATOR_H

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace TestsAlwaysIncluded\HealthCheck\Tests\Test;

use TestsAlwaysIncluded\HealthCheck\Test\Test;
use TestsAlwaysIncluded\HealthCheck\Test\TestGroup;

class TestGroupTest extends \PHPUnit_Framework_TestCase
{
    protected function makeTest($name)
    {
        return $this->getMockBuilder('TestsAlwaysIncluded\HealthCheck\Test\Test')
            ->setConstructorArgs(array($name))
            ->getMockForAbstractClass();
    }

    public function testSetGetName()
    {
        $name = 'hello';
        $testGroup = new TestGroup();
        $testGroup->setName($name);
        $this->assertSame($name, $testGroup->getName());
    }

    public function testSetGetTests()
    {
        $test = $this->makeTest('TEST#1');
        $test2 = $this->makeTest('TEST#2');
        $testGroup = new TestGroup();
        $tests = array(
            $test,
            $test2
        );
        $testGroup->setTests($tests);
        $this->assertSame($tests, $testGroup->getTests());
    }

    public function testAddTest()
    {
        $test = $this->makeTest('TEST');
        $testGroup = new TestGroup();
        $testGroup->addTest($test);
        $expected = array(
            $test,
        );
        $this->assertSame($expected, $testGroup->getTests());
    }
}


text:
<?php

namespace Oro\Bundle\MigrationBundle\Migration;

use Psr\Log\LoggerInterface;

class ParametrizedSqlMigrationQuery extends ParametrizedMigrationQuery
{
    /**
     * @var array value = [sql, parameters, types]
     */
    protected $queries = [];

    /**
     * Adds SQL query
     *
     * @param string $query  The SQL query
     * @param array  $params The parameters to bind to the query, if any.
     * @param array  $types  The types the previous parameters are in.
     */
    public function __construct($query = null, array $params = [], array $types = [])
    {
        if (!empty($query)) {
            $this->queries[] = [$query, $params, $types];
        }
    }

    /**
     * Adds SQL query
     *
     * @param string $query  The SQL query
     * @param array  $params The parameters to bind to the query, if any.
     * @param array  $types  The types the previous parameters are in.
     */
    public function addSql($query, array $params = [], array $types = [])
    {
        $this->queries[] = [$query, $params, $types];
    }

    /**
     * {@inheritdoc}
     */
    public function getDescription()
    {
        $logger = new ArrayLogger();
        $this->processQueries($logger, true);

        return $logger->getMessages();
    }

    /**
     * {@inheritdoc}
     */
    public function execute(LoggerInterface $logger)
    {
        $this->processQueries($logger);
    }

    /**
     * @param LoggerInterface $logger
     * @param bool            $dryRun
     */
    protected function processQueries(LoggerInterface $logger, $dryRun = false)
    {
        foreach ($this->queries as $query) {
            $this->logQuery($logger, $query[0], $query[1], $query[2]);
            if (!$dryRun) {
                $this->connection->executeUpdate($query[0], $query[1], $query[2]);
            }
        }
    }
}


text:
  Wherever  you see a path to a file that starts with *[repository root]*, replace it with the absolute path to the folder in which the 20487 repository resides.
  For example, if you cloned or extracted the 20487 repository to **C:\Users\John Doe\Downloads\20487**, the following path: **[repository root]\AllFiles\20487C\Mod06** should be changed to **C:\Users\John Doe\Downloads\20487\AllFiles\20487C\Mod06**.

# Lesson 1: Hosting Services On-Premises

### Demonstration: How to Host WCF Services in IIS

#### Preparation Steps

You need to activate Microsoft Internet Information Services (IIS) on your machine. The instructions below are for Windows 10 only.

1. To open the **Search** window,click the magnifying glass next to the Start menu.
2. Type **Turn windows features on or off**, and then press Enter.
3. Select the **Internet Information Services** once, a black square should appear within the check box.
4. Expand **Internet Information Services**, and then expand **World Wide Web Services**.
5. Select the **Application Development Features** check boxes.
6. Expand the **Common HTTP Features** and select all the check boxes.
7. You will also need to activate WCF support before you can deploy WCF services to IIS. To do this:
8. In the **Windows Features window**, expand **.NET Framework 4.7 Advances Services**.
Expand **WCF Services**, and then select all the check boxes inside it (HTTP Activation, Message Queuing (MSMQ) Activation, and so on).
Click **Ok**, Windows proceeds to install the required components; when it is done, IIS will be running.

8. Verify that IIS works:
	a) Open a browser.
	b) Navigate to **http://localhost/**, an Internet Information Services page should appear.

#### Demonstration Steps

1. Click **Start** and in the Search box type **Visual Studio**. In the list of search results, right-click **Visual Studio 2017**, and then click **Run as administrator**, in **User Control** dislog box click **Yes**.
2. On the **File** menu, point to **New**, and then click **Project**.
3. In navigation pane of the **New Project** dialog box, expand the **Installed** node, and then expand the **Visual C#** node.
4. Click the **WCF** node, and then from the list of templates, select **WCF Service Application**.
5. In the **Name** text box, type **MyIISService**.
6. In the **Location** text box, type **[repository root]\Allfiles\20487C\Mod06\DemoFiles\WCF**.
7. Clear the **Create directory for solution** check box, and then click **OK**.
8. In Solution Explorer, under the **MyIISService** project, double-click **web.config**.

    >**Note**: The reason there is no <services> section in the <system.serviceModel> is because IIS automatically defines the base address according to the virtual directory where the services are hosted, and the default endpoint configuration of WCF therefore does not require any specific configuration for each endpoint.

9. In Solution Explorer, under the **MyIISService** project, right-click **Service1.svc**, and then click **View Markup**.

    >**Note**: When IIS receives a request addressed to the .svc file, it uses the value of the **Service** attribute from the file to know which service it needs to call.

10. In Solution Explorer, click the **MyIISService** project node.
11. To build and debug the application, press F5. After the application is built, a browser opens.
12. In opened browser window, locate the address bar. To the base address of the service, add the absolute path: **Service1.svc?wsdl**, and then press Enter. Review the **Web Services Description Language (WSDL)** file.

    >**Note**: Lesson 4, "Consuming WCF Services" in Module 5, "Creating WCF Services" of Course 20487 explains how to use WSDL to generate service proxies.

13. To stop the debugger, return to Visual Studio and press Shift+F5.
14. Publish the service to IIS. To do this:
	a. In Solution Explorer, right-click the **MyIISService** project, and then click **Publish**. The **Publish** tab opens.
	b. Select **IIS, FTP, etc**, and then click **Publish**. The **Publish** window opens.
	c. In **Publish method**, select **Web Deploy**.
	d. In **Server**, type **localhost**.
	e. In **Site Name**, type **Default Web Site/MyIISService**.
	f. In **Destination URL**, type **http://localhost/MyIISService/Service1.svc?wsdl**.
	g. Click **Save**.

    Visual Studio 2017 proceeds to build and deploy the service to IIS. When it's done, a browser automatically opens and navigates to the service WSDL.

15. Review the WCF service WSDL.
16. Close all open windows.

# Lesson 2: Hosting Services in Microsoft Azure

### Demonstration: Hosting in Microsoft Azure

#### Demonstration Steps

1.  Click **Start**, type **Visual Studio**. From the search results, right-click **Visual Studio 2017**, and then select **Run as administrator**, In User **Control dialog** box  click **Yes**.
2.  On the **File** menu, point to **New**, and then click **Project**.
3.  In the **New Project** dialog box, on the navigation pane, expand the  **Installed** node, expand the **Visual C\#** node, click the **Web** node, and then in the list of templates, click **ASP.NET Web Application(.NET Framework)**.
4.  In the **Name** text box, type **MyWebSite**.
5.  In the **Location** text box, type **[repository root]\Allfiles\20487C\Mod06\DemoFiles\DeployWebApp**.
6.  Clear the **Create directory for solution** check box, and then click **OK**.
7.  In the **New ASP.NET Web Application** dialog box, select **Web API**, and then click **OK**.
8.	Open **Microsoft Edge** and go to **https://portal.azure.com**.
9.	If a page appears asking for your email address, enter your email address, and then click **Next**. Wait for the sign in page to appear, enter your email address and password, and then click **Sign In**.

	>**Note :** If during sign in, a page appears asking you to choose from a list of previously used accounts, select the account you previously used, and then enter your credentials.

10.	In the left menu of the portal, click **App Services**.
11. In the action bar, click **Add**, select **Web APP**, and then at the bottom of the third screen, click **Create** .
12.	In the **App name** box, type the name **wawsdemo***YourInitials* (YourInitials contains your initials). This is a unique value, which when combined with the **.azurewebsites.net** suffix is used as the URL to your web app.
13. In the **Resource Group** section, select **Create new**, and then change the name of the Resource Group to **BlueYonder.Demo.06**.
12.	Click **App Service Plan/Location** and then click **Create new**.
13. In the **App Service Plan** box, type **BlueYonderDemo06**.
14.	In the **Location** drop-down list, select the region closest to your location.
15. In the **Pricing tier** section, select **D1 Shared**, and then click **OK**.
16. Click **Create** . The site is added to the Web Apps table and its status is set to **Creating**.
17.	After the status changes to **Running**, in Visual Studio, on the **View** menu, click **Server Explorer**.
18.	In **Server Explorer**, right-click the **Azure** pane, and then click **Connect To Microsoft Azure Subscription**.
19.	On the login screen, if a page appears asking you to choose from a list of previously used accounts, select the account you previously used, enter your credentials, and then click **Sign in**.

    >**NOTE :**	Wait until the login process completes.
        You only need to perform this step once, to import your Microsoft Azure account settings to Visual Studio.
        Now **Visual Studio 2017** can display the list of Web Apps and Cloud Services to which you can deploy applications.

20.	In Visual Studio, in **Solution Explorer**, right-click **MyWebSite** project, and then click **Publish**.
21.	In the **Pick a publish target** dialog box, choose **App Services**, in the **Microsoft Azure App Service** view, select the **Select Existing** option, and then click **Publish**.
22.	In the **App Service** dialog box, expand **BlueYonder.Demo.06** folder, select **wawsdemoYourInitial**, and then click **OK**.
23. Click **Publish**. Visual Studio publishes the application according to the settings that are provided in the profile file. After deployment finishes, Visual Studio opens Internet Explorer and displays the web app. The deployment process is quick, because the process only copies the content of the application to an existing virtual machine and does not need to wait for a new virtual machine to be created.
24. Close all open windows.

©2018 Microsoft Corporation. All rights reserved.

The text in this document is available under the [Creative Commons Attribution 3.0 License](https://creativecommons.org/licenses/by/3.0/legalcode), additional terms may apply. All other content contained in this document (including, without limitation, trademarks, logos, images, etc.) are **not** included within the Creative Commons license grant. This document does not provide you with any legal rights to any intellectual property in any Microsoft product. You may copy and use this document for your internal, reference purposes.

This document is provided "as-is." Information and views expressed in this document, including URL and other Internet Web site references, may change without notice. You bear the risk of using it. Some examples are for illustration only and are fictitious. No real association is intended or inferred. Microsoft makes no warranties, express or implied, with respect to the information provided here.


text:
package cn.api.model;

import java.io.Serializable;

public class Section implements Serializable {
    /**
     * productCode      产品id
     * sectionId        专区id
     * name             专区名字
     * image1                            缩略图地址
     */
    private String productCode = "";
    private int sectionId = -1;
    private String name = "";
    private String image1 = "";
    private String image2 = "";
    private String image3 = "";
    private String image4 = "";

    public String getProductCode() {
        return productCode;
    }

    public void setProductCode(String productCode) {
        this.productCode = productCode;
    }

    public int getSectionId() {
        return sectionId;
    }

    public void setSectionId(int sectionId) {
        this.sectionId = sectionId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getImage1() {
        return image1;
    }

    public void setImage1(String image1) {
        this.image1 = image1;
    }

    public String getImage2() {
        return image2;
    }

    public void setImage2(String image2) {
        this.image2 = image2;
    }

    public String getImage3() {
        return image3;
    }

    public void setImage3(String image3) {
        this.image3 = image3;
    }

    public String getImage4() {
        return image4;
    }

    public void setImage4(String image4) {
        this.image4 = image4;
    }

}


text:
namespace ohmmsqmc
{

class TriCubicSplineSet
{

  bool OwnGrid;

  /// the number of Spline orbitals
  int norbs;

  /// the initial and final corners of the Schroedinger's region
  gridvec_t ri,rf;

  /// pointer to the full grid
  Grid3D* DeviceGrid;

  /// pointer to the Schroedinger grid
  Grid3D* Schr_Grid;

  /// the vector of pointers to all the orbitals
  std::vector<TriCubicSpline*> m_psi;

  /// class to set r-point parameters
  SetSplinePoint* m_set;

  /// read all the wave-functions from the input file
  void readwf(const char*, int ispin, int num);

  std::map<string,int> orbital_map;

public:

  /// constructor
  TriCubicSplineSet();

  /// destructor
  ~TriCubicSplineSet();

  /// reading in the input data
  bool put(xmlNodePtr, Grid3D*);

  /// a function to set the two grid pointers
  inline void set(Grid3D* fg, Grid3D* Sg)
  {
    DeviceGrid = fg;
    Schr_Grid = Sg;
  }

  inline int size() const
  {
    return m_psi.size();
  }

  /// return the fullGrid
  Grid3D* get_DeviceGrid()
  {
    return DeviceGrid;
  }

  /// return an orbital
  TriCubicSpline* getOrbital(int i)
  {
    return m_psi[i];
  }

  /// setting the point r parameters
  inline void set_point(const posvec_t& r)
  {
    m_set->set_point(r,Schr_Grid);
  }

  /// initialising the padded function
  void finit(int);

  inline TriCubicSpline* getOrbital(const string& orbname)
  {
    std::map<string,int>::iterator it = orbital_map.find(orbname);
    if(it == orbital_map.end())
      return NULL;
    else
      return m_psi[(*it).second];
  }

  /// evaluate the wavefunction
  void evaluate(const posvec_t&,scalar_array_t&,posarray_t&,scalar_array_t&);

  /// more esoteric evaluation
  template<class PTCL, class VM, class GM>
  inline void evaluate(const PTCL& P, int first, int last,
                       VM& logdet, GM& dlogdet, VM& d2logdet)
  {
    int n = last-first;
    int iat = first;
    for(int i=0; i < n; i++,iat++)
    {
      set_point(P.R[iat],Schr_Grid);   /// set the r-point parameters
      for(int j=0; j < n; j++)
      {
        logdet(j,i)= m_psi[j]->evaluate(P.R[iat], dlogdet(i,j),d2logdet(i,j));
      }
    }
  }

};

}
#endif


text:
define('controllers/edit', [
	'views/test-form',
	'views/questions-forms',
	'views/answers-form',
	'steps',
	'ajax',
	'promise',
	'uuid',
	'store',
	'clone',
	'utils',
	'notify',
	'lang'
], function (
	TestForm,
	questionsForms,
	AnswersForm,
	steps,
	ajax,
	Promise,
	uuid,
	store,
	clone,
	utils,
	notify,
	__
) {

	var form = new TestForm({
		node: '#test-form'
	});

	var answersForm = new AnswersForm({
		node: '#answers-form'
	});

	form.callbacks.save = function (data) {
		data.course_id = store.course.id;
		return ajax('/teacher/courses/test', data).then(function (test) {
			notify.success(__('main.saved'));
			steps('tests', {oldTest: form.test, newTest: test});
		});
	};

	form.callbacks.cancel = function () {
		steps('tests');
	};

	form.callbacks.addQuestion = function (type, parent) {
		var list = !parent.composer ? parent.model('questions') : parent.model('question').model('questions');
		var data = type.data();
		data.uuid = uuid();
		list.add(data);
	};

	form.callbacks.editQuestion = function (question) {
		questionsForms.open({
			question: question.data.question,
			save: function (data) {
				question.model('question').assign(data);
			}
		});
	};

	form.callbacks.cloneQuestion = function (question) {
		var list = question.parent === question.composer ? question.parent.model('questions') : question.parent.model(['question', 'questions']);
		list.add(clone(question.data.question), list.indexOf(question.data.question) + 1);
	};

	form.callbacks.deleteQuestion = function (question) {
		if (!confirm(__('main.are_you_sure'))) return;

		var list = question.parent === question.composer ? question.parent.model('questions') : question.parent.model(['question', 'questions']);
		list.remove(question.data.question);
	};

	form.callbacks.showUsers = function (answers) {
		var ids = answers.map(function (answer) {
			return answer.user_id;
		});

		ajax('users', {ids: ids}).then(function (users) {
			users = utils.indexBy(users, 'id');

			answersForm.open({users: answers.map(function (answer) {
				var user = clone(users[answer.user_id]);
				user.time = answer.time;
				return user;
			})});
		});
	};

	steps.on('test-form', function (test) {
		form.clear();

		var p;

		if (test.id) {
			p = Promise.all([
				ajax('questions', {id: test.id}),
				ajax('answers', {id: test.id})
			]);
		}
		else {
			p = Promise.resolve([[], []]);
		}

		p.then(function (data) {
			form.open({
				test: utils.extend(clone(test), {
					questions: data[0],
					answers: data[1]
				})
			});
		});
	});
});


text:
#region Apache License 2.0

// Copyright 2015 Thaddeus Ryker
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#endregion

using System;
using Org.Edgerunner.DotSerialize.Attributes;

namespace Org.Edgerunner.DotSerialize.Tests.DataTypes
{
   public struct Bone
   {
      #region TypeOf enum

      public enum TypeOf
      {
         Chicken,
         Fish,
         Steak,
         Turkey
      }

      #endregion

      [XmlAttribute] public TypeOf Type { get; set; }
      [XmlAttribute] public double Width { get; set; }
      [XmlAttribute] public double Diameter { get; set; }
   }
}


text:
The RNTester showcases React Native views and modules.

## Running this app

Before running the app, make sure you ran:

    git clone https://github.com/facebook/react-native.git
    cd react-native
    yarn install

### Running on iOS

If you are testing non-fabric component, modify [the fabric_enabled flag in RNTester's Podfile](https://github.com/facebook/react-native/blob/main/packages/rn-tester/Podfile#L24).

```ruby
fabric_enabled = false
```

Also, if you previously built RNTester with fabric enabled, you might need to clean up the build files and Pods.
```sh
# Clean the generated files and folders to clean install RNTester
cd packages/rn-tester
yarn clean-ios
```

If you are still having a problem after doing the clean up (which can happen if you have built RNTester with older React Native versions where files were generated inside the react-native folder.), the best way might be to clean-install react-native (e.g. remove node_modules and yarn install).

Both macOS and Xcode are required.
1. `cd packages/rn-tester`
1. Install [Bundler](https://bundler.io/): `gem install bundler`. We use bundler to install the right version of [CocoaPods](https://cocoapods.org/) locally.
1. Install Bundler and CocoaPods dependencies: `bundle install && bundle exec pod install` or `yarn setup-ios-hermes`. In order to use JSC instead of Hermes engine, run: `USE_HERMES=0 bundle exec pod install` or `yarn setup-ios-jsc` instead.
1. Open the generated `RNTesterPods.xcworkspace`. This is not checked in, as it is generated by CocoaPods. Do not open `RNTesterPods.xcodeproj` directly.

#### Note for M1 users
If you own a Mac M1 laptop, you need to run some different commands to install and run cocoapods.

- `sudo arch -x86_64 gem install ffi`: this installs the `ffi` package to load dynamically-linked libraries.
- `arch -x86_64 pod install`: this run `pod install` with the right architecture.

### Running on Android

You'll need to have all the [prerequisites](https://reactnative.dev/contributing/how-to-build-from-source#prerequisites) (SDK, NDK) for Building React Native installed.

Start an Android emulator.

```sh
cd packages/rn-tester
# In order to use Hermes engine, run `yarn install-android-hermes` instead.
yarn install-android-jsc
yarn start
```

_Note: Building for the first time can take a while._

Open the RNTester app in your emulator.
If you want to use a physical device, run `adb devices`, then `adb -s <device name> reverse tcp:8081 tcp:8081`.
See [Running on Device](https://reactnative.dev/docs/running-on-device) for additional instructions on using a physical device.

### Running with Buck

Follow the same setup as running with gradle.

Install Buck from [here](https://buckbuild.com/setup/install.html).

Run the following commands from the react-native folder:

    ./gradlew :ReactAndroid:packageReactNdkLibsForBuck
    buck fetch rntester
    buck install -r rntester
    ./scripts/packager.sh

_Note: The native libs are still built using gradle. Full build with buck is coming soon(tm)._

## Building from source

Building the app on both iOS and Android means building the React Native framework from source. This way you're running the latest native and JS code the way you see it in your clone of the github repo.

This is different from apps created using `react-native init` which have a dependency on a specific version of React Native JS and native code, declared in a `package.json` file (and `build.gradle` for Android apps).


text:
This module provides convenience functions for creating _breadcrumb_ navigation elements.

#### `CrumbTrail`

``` purescript
data CrumbTrail a
  = CrumbTrail [Tuple String (Target a)] String [Tuple String (Target a)]
```

A `CrumbTrail` is a zipper with a current location, and crumbs behind and in front of us.

#### `breadcrumbs`

``` purescript
breadcrumbs :: forall p i. CrumbTrail i -> H.HTML p i
```

Create a breadcrumb navigation element from an array of `Crumb`s.

## Module Halogen.Themes.Bootstrap3.InputGroup

This module provides convenience functions for creating _input groups_.

#### `AddOn`

``` purescript
data AddOn p i
  = RegularAddOn (H.HTML p i)
  | ButtonAddOn (H.HTML p i)
```

Represents an input group add-on element

We need to distinguish buttons from regular add-ons because of the
different CSS classes

#### `inputGroup`

``` purescript
inputGroup :: forall p i. Maybe (AddOn p i) -> H.HTML p i -> Maybe (AddOn p i) -> H.HTML p i
```

Create an input group.

An input group consists of a control with optional elements placed before and after.

## Module Halogen.Themes.Bootstrap3.Navbar

This module provides convenience functions for creating Bootstrap _navbars_.

#### `NavLink`

``` purescript
type NavLink a = { target :: Target a, active :: Boolean, text :: String }
```

A simple navigation link

#### `Link`

``` purescript
type Link a = { target :: Target a, text :: String }
```

Link text and target

#### `NavDropDown`

``` purescript
type NavDropDown a = { groups :: [[Link a]], text :: String }
```

#### `NavItem`

``` purescript
data NavItem a
  = NavLink (NavLink a)
  | NavDropDown (NavDropDown a)
```

Enumerates the different kinds of navigation item

#### `Nav`

``` purescript
type Nav a = { items :: [NavItem a] }
```

A navigation menu configuration

#### `NavBarItem`

``` purescript
data NavBarItem a
  = Brand (Link a)
  | Nav (Nav a)
  | Text String
  | Button (Link a)
```

Enumerates the different kinds of item which can be rendered in a navbar

#### `NavBar`

``` purescript
type NavBar a = { items :: [NavBarItem a] }
```

A navbar configuration

#### `navbar`

``` purescript
navbar :: forall p i. NavBar i -> H.HTML p i
```

Create a navbar from a configuration object.


text:
class Config;

namespace Simulator
{

class LCD : public IIOMessageClient, public Object
{
    IOMessageInterface& m_ioif;
    IODeviceID m_devid;
    char*      m_buffer;

    size_t     m_width;
    size_t     m_height;

    size_t     m_startrow;
    size_t     m_startcolumn;

    unsigned   m_bgcolor;
    unsigned   m_fgcolor;

    DefineStateVariable(size_t, curx);
    DefineStateVariable(size_t, cury);

    std::ofstream *m_tracefile;

    void Refresh(unsigned firstrow, unsigned lastrow) const;

public:
    LCD(const std::string& name, Object& parent, IOMessageInterface& iobus, IODeviceID devid);
    LCD(const LCD&) = delete;
    LCD& operator=(const LCD&) = delete;
    ~LCD();

    bool OnReadRequestReceived(IODeviceID from, MemAddr address, MemSize size) override;
    StorageTraceSet GetReadRequestTraces() const override;
    bool OnWriteRequestReceived(IODeviceID from, MemAddr address, const IOData& data) override;
    StorageTraceSet GetWriteRequestTraces() const override;

    void GetDeviceIdentity(IODeviceIdentification& id) const override;

    const std::string& GetIODeviceName() const override;
};

}

#endif


text:
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('ggf-tournament/card', 'Integration | Component | ggf tournament/card', {
  integration: true
});

test('it renders', function(assert) {
  assert.expect(2);

  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });

  this.render(hbs`{{ggf-tournament/card}}`);

  assert.equal(this.$().text(), '');

  // Template block usage:
  this.render(hbs`
    {{#ggf-tournament/card}}
      template block text
    {{/ggf-tournament/card}}
  `);

  assert.equal(this.$().text().trim(), 'template block text');
});


text:
from PyQt4 import QtGui, QtCore
from acq4.Manager import getManager, logExc, logMsg
from acq4.devices.Laser.devTemplate import Ui_Form
from acq4.devices.Laser.LaserDevGui import LaserDevGui
from maiTaiTemplate import Ui_MaiTaiStatusWidget
import numpy as np
from scipy import stats
from acq4.pyqtgraph.functions import siFormat
import time

class MaiTaiDevGui(LaserDevGui):

    def __init__(self, dev):
        LaserDevGui.__init__(self,dev)
        self.dev = dev
        #self.dev.devGui = self  ## make this gui accessible from LaserDevice, so device can change power values. NO, BAD FORM (device is not allowed to talk to guis, it can only send signals)
        #self.ui = Ui_Form()
        #self.ui.setupUi(self)

        self.calibrateWarning = self.dev.config.get('calibrationWarning', None)
        self.calibrateBtnState = 0

        ### configure gui
        ### hide group boxes which are not related to Mai Tai function
        self.ui.buttonGroup.hide()
        self.ui.wavelengthGroup.hide()

        # setup Mai Tai widget
        self._maitaiui = Ui_MaiTaiStatusWidget()
        self._maitaiwidget = QtGui.QWidget()
        self._maitaiui.setupUi(self._maitaiwidget)
        # insert Mai Tai widget in Laser GUI
        self.ui.verticalLayout_2.insertWidget(0, self._maitaiwidget)

        if self.dev.isLaserOn():
            self.onOffToggled(True)
            self._maitaiui.turnOnOffBtn.setChecked(True)
            if self.dev.getInternalShutter():
                self.internalShutterToggled(True)
                self._maitaiui.InternalShutterBtn.setChecked(True)
            self._maitaiui.InternalShutterBtn.setEnabled(True)
        else:
            self._maitaiui.InternalShutterBtn.setEnabled(False)

        #self.ui.MaiTaiGroup.hide()
        #self.ui.turnOnOffBtn.hide()

        startWL = self.dev.getWavelength()
        self._maitaiui.wavelengthSpin_2.setOpts(suffix='m', siPrefix=True, dec=False, step=5e-9)
        self._maitaiui.wavelengthSpin_2.setValue(startWL)
        self._maitaiui.wavelengthSpin_2.setOpts(bounds=self.dev.getWavelengthRange())
        self._maitaiui.currentWaveLengthLabel.setText(siFormat(startWL, suffix='m'))

        self._maitaiui.wavelengthSpin_2.valueChanged.connect(self.wavelengthSpinChanged)

        self._maitaiui.turnOnOffBtn.toggled.connect(self.onOffToggled)
        self._maitaiui.InternalShutterBtn.toggled.connect(self.internalShutterToggled)
        self._maitaiui.ExternalShutterBtn.toggled.connect(self.externalShutterToggled)
        self._maitaiui.externalSwitchBtn.toggled.connect(self.externalSwitchToggled)
        self._maitaiui.linkLaserExtSwitchCheckBox.toggled.connect(self.linkLaserExtSwitch)
        self._maitaiui.alignmentModeBtn.toggled.connect(self.alignmentModeToggled)

        self.dev.sigOutputPowerChanged.connect(self.outputPowerChanged)
        self.dev.sigSamplePowerChanged.connect(self.samplePowerChanged)
        self.dev.sigPumpPowerChanged.connect(self.pumpPowerChanged)
        self.dev.sigRelativeHumidityChanged.connect(self.relHumidityChanged)
        self.dev.sigPulsingStateChanged.connect(self.pulsingStateChanged)
        self.dev.sigWavelengthChanged.connect(self.wavelengthChanged)
        self.dev.sigModeChanged.connect(self.modeChanged)
        self.dev.sigP2OptimizationChanged.connect(self.p2OptimizationChanged)
        self.dev.sigHistoryBufferChanged.connect(self.historyBufferChanged)
        self.dev.sigHistoryBufferPumpLaserChanged.connect(self.historyBufferPumpLaserChanged)

    def onOffToggled(self, b):
        if b:
            self.dev.switchLaserOn()
            self._maitaiui.turnOnOffBtn.setText('Turn Off Laser')
            self._maitaiui.turnOnOffBtn.setStyleSheet("QLabel {background-color: #C00}")
            self._maitaiui.EmissionLabel.setText('Emission ON')
            self._maitaiui.EmissionLabel.setStyleSheet("QLabel {color: #C00}")
            self._maitaiui.InternalShutterBtn.setEnabled(True)
        else:
            self.dev.switchLaserOff()
            self.shutterToggled(False)
            self._maitaiui.turnOnOffBtn.setText('Turn On Laser')
            self._maitaiui.turnOnOffBtn.setStyleSheet("QLabel {background-color: None}")
            self._maitaiui.EmissionLabel.setText('Emission Off')
            self._maitaiui.EmissionLabel.setStyleSheet("QLabel {color: None}")
            self._maitaiui.InternalShutterBtn.setEnabled(False)

    def internalShutterToggled(self, b):
        if b:
            if self._maitaiui.linkLaserExtSwitchCheckBox.isChecked():
                self.dev.externalSwitchOFF()
                self._maitaiui.externalSwitchBtn.setChecked(False)
                self._maitaiui.externalSwitchBtn.setText('External Switch OFF')
            self.dev.openInternalShutter()
            self._maitaiui.InternalShutterBtn.setText('Close Laser Shutter')
            self._maitaiui.InternalShutterLabel.setText('Laser Shutter Open')
            self._maitaiui.InternalShutterLabel.setStyleSheet("QLabel {color: #0A0}")
        elif not b:
            self.dev.closeInternalShutter()
            self._maitaiui.InternalShutterBtn.setText('Open Laser Shutter')
            #self._maitaiui.shutterBtn.setStyleSheet("QLabel {background-color: None}")
            self._maitaiui.InternalShutterLabel.setText('Laser Shutter Closed')
            self._maitaiui.InternalShutterLabel.setStyleSheet("QLabel {color: None}")
            if self._maitaiui.linkLaserExtSwitchCheckBox.isChecked():
                self.dev.externalSwitchON()
                self._maitaiui.externalSwitchBtn.setChecked(True)
                self._maitaiui.externalSwitchBtn.setText('External Switch ON')

    def externalShutterToggled(self, b):
        if b:
            self.dev.openShutter()
            self._maitaiui.ExternalShutterBtn.setText('Close External Shutter')
            self._maitaiui.ExternalShutterLabel.setText('External Shutter Open')
            self._maitaiui.ExternalShutterLabel.setStyleSheet("QLabel {color: #10F}")
        elif not b:
            self.dev.closeShutter()
            self._maitaiui.ExternalShutterBtn.setText('Open External Shutter')
            self._maitaiui.ExternalShutterLabel.setText('External Shutter Closed')
            self._maitaiui.ExternalShutterLabel.setStyleSheet("QLabel {color: None}")

    def externalSwitchToggled(self,b):
        if b:
            self.dev.externalSwitchON()
            self._maitaiui.externalSwitchBtn.setText('External Switch ON')
        elif not b:
            self.dev.externalSwitchOFF()
            self._maitaiui.externalSwitchBtn.setText('External Switch OFF')

    def linkLaserExtSwitch(self,b):
        if b:
            self._maitaiui.externalSwitchBtn.setEnabled(False)
        elif not b:
            self._maitaiui.externalSwitchBtn.setEnabled(True)

    def alignmentModeToggled(self,b):
        if b:
            self.dev.acitvateAlignmentMode()
            self._maitaiui.alignmentModeBtn.setText('Alignment Mode ON')
        elif not b:
            self.dev.deactivateAlignmentMode()
            self._maitaiui.alignmentModeBtn.setText('Alignment Mode OFF')

    def wavelengthChanged(self,wl):
        if wl is None:
            self._maitaiui.currentWaveLengthLabel.setText("?")
        else:
            self._maitaiui.currentWaveLengthLabel.setText(siFormat(wl, suffix='m'))

    def wavelengthSpinChanged(self, value):
        self.dev.setWavelength(value)
        #if value not in self.dev.config.get('namedWavelengths', {}).keys():
        #    self._maitaiui.wavelengthCombo.setCurrentIndex(0)

    def samplePowerChanged(self, power):
        if power is None:
            self.ui.samplePowerLabel.setText("?")
        else:
            self.ui.samplePowerLabel.setText(siFormat(power, suffix='W'))

    def outputPowerChanged(self, power, valid):
        if power is None:
            self.ui.outputPowerLabel.setText("?")
        else:
            self.ui.outputPowerLabel.setText(siFormat(power, suffix='W'))

        self.ui.outputPowerLabel.setStyleSheet("QLabel {color: #C00}")
        #if not valid:
        #    self.ui.outputPowerLabel.setStyleSheet("QLabel {color: #C00}")
        #else:
        #    self.ui.outputPowerLabel.setStyleSheet("QLabel {color: #000}")

    def p2OptimizationChanged(self,p2Opt):
        if p2Opt is None:
            self._maitaiui.P2OptimizationLabel.setText("?")
        elif p2Opt:
            self._maitaiui.P2OptimizationLabel.setText("ON")
        elif not p2Opt:
            self._maitaiui.P2OptimizationLabel.setText("OFF")

    def historyBufferChanged(self, hist):
        if hist is None:
            self._maitaiui.systemStatusLabel.setText("?")
        else:
            self._maitaiui.systemStatusLabel.setText(str(hist))

    def historyBufferPumpLaserChanged(self, histPL):
        if histPL is None:
            self._maitaiui.pumpLaserSystemStatusLabel.setText("?")
        else:
            self._maitaiui.pumpLaserSystemStatusLabel.setText(str(histPL))

    def pumpPowerChanged(self,pumpPower):
        if pumpPower is None:
            self._maitaiui.pumpPowerLabel.setText("?")
        else:
            self._maitaiui.pumpPowerLabel.setText(siFormat(pumpPower, suffix='W'))

    def relHumidityChanged(self, humidity):
        if humidity is None:
            self._maitaiui.relHumidityLabel.setText("?")
        else:
            self._maitaiui.relHumidityLabel.setText(siFormat(humidity, suffix='%'))

    def modeChanged(self, mode):
        if mode is None:
            self._maitaiui.pumpModeLabel.setText("?")
        else:
            self._maitaiui.pumpModeLabel.setText(mode)

    def pulsingStateChanged(self, pulsing):
        if pulsing:
            self._maitaiui.PulsingLabel.setText('Pulsing')
            self._maitaiui.PulsingLabel.setStyleSheet("QLabel {color: #EA0}")
        else:
            self._maitaiui.PulsingLabel.setText('Not Pulsing')
            self._maitaiui.PulsingLabel.setStyleSheet("QLabel {color: None}")