/// <summary>
        /// Records a value to the values array of this sample given the zero-based index of the value definition to be used.
        /// </summary>
        /// <remarks>The value must be defined as part of the event metric definition associated with this sample
        /// or an exception will be thrown.  The data type must also be compatible with the data type configured
        /// on the event metric definition or no data will be recorded.
        /// If called more than once for the same value, the prior value will be replaced.</remarks>
        /// <param name="valueIndex">The zero-based index within the value definition of the value to be recorded.</param>
        /// <param name="value">The value to be recorded.</param>
        public void SetValue(int valueIndex, object value)
        {
            IEventMetricValueDefinitionCollection valueDefinitions = Metric.Definition.Values;

            //we don't have to check that the value index isn't null, but it does have to be in range
            if ((valueIndex < 0) || (valueIndex > (valueDefinitions.Count - 1)))
            {
#if DEBUG
                //if we're compiled in debug mode, tell the user they blew it.
                throw new ArgumentOutOfRangeException(nameof(valueIndex), valueIndex.ToString(CultureInfo.CurrentCulture));
#else
                //log and return, nothing we can do.
                if (!Log.SilentMode)
                {
                    Log.Write(LogMessageSeverity.Warning, LogCategory, "Unable to add metric value to the current sample due to missing value definition",
                              "There is no value definition at index {1} for metric definition {0}",
                              Metric.Definition.Name, valueIndex);
                }
                return;
#endif
            }

            //look up the value in the definition so we can process it
            IEventMetricValueDefinition curValueDefinition = valueDefinitions[valueIndex];

            //and now we can use our one true method to add the value
            SetValue((EventMetricValueDefinition)curValueDefinition, value);
        }
        /// <summary>
        /// Register this instance as a completed definition and return the valid usable definition for this event metric.
        /// </summary>
        /// <remarks>This call is necessary to complete a new event metric definition (created by calls to AddValue) before
        /// it can be used, and it signifies that all desired value columns have been added to the definition.  Only the
        /// first registration of a metric definition with a given Key (metrics system, category name, and counter name)
        /// will be effective and return the same definition object; subsequent calls (perhaps by another thread) will
        /// instead return the existing definition already registered.  If a definition already registered with that Key
        /// can not be an event metric (e.g. a sampled metric is defined with that Key) or if this instance defined value
        /// columns not present as compatible value columns in the existing registered definition with that Key, then an
        /// ArgumentException will be thrown to signal your programming mistake.</remarks>
        /// <returns>The actual usable definition with the same metrics system, category name, and counter name as this instance.</returns>
        public EventMetricDefinition Register()
        {
            EventMetricDefinition      officialDefinition;
            MetricDefinitionCollection definitionCollection = (MetricDefinitionCollection)Definitions;

            // We need to lock the collection while we check for an existing definition and maybe add this one to it.
            lock (definitionCollection.Lock)
            {
                IMetricDefinition rawDefinition;
                if (definitionCollection.TryGetValue(MetricTypeName, CategoryName, CounterName, out rawDefinition) == false)
                {
                    // There isn't already one by that Key.  Great!  Register ourselves.
                    SetReadOnly(); // Mark this definition as completed.
                    officialDefinition = this;
                    definitionCollection.Add(this);
                }
                else
                {
                    // Oooh, we found one already registered.  We'll want to do some checking on this, but outside the lock.
                    officialDefinition = rawDefinition as EventMetricDefinition;
                }
            } // End of collection lock

            if (officialDefinition == null)
            {
                throw new ArgumentException(
                          string.Format(
                              "There is already a metric definition for the same metrics system ({0}), category name ({1}), and counter name ({2}), but it is not an event metric.",
                              MetricTypeName, CategoryName, CounterName));
            }
            else if (this != officialDefinition)
            {
                // There was one other than us, make sure it's compatible with us.
                IEventMetricValueDefinitionCollection officialValues = officialDefinition.Values;
                foreach (EventMetricValueDefinition ourValue in Values)
                {
                    IEventMetricValueDefinition officialValue;
                    if (officialValues.TryGetValue(ourValue.Name, out officialValue) == false)
                    {
                        // It doesn't have one of our value columns!
                        throw new ArgumentException(
                                  string.Format(
                                      "There is already an event metric definition for the same metrics system ({0}), category name ({1}), and counter name ({2}), but it is not compatible; it does not define value column \"{3}\".",
                                      MetricTypeName, CategoryName, CounterName, ourValue.Name));
                    }
                    else if (ourValue.SerializedType != ((EventMetricValueDefinition)officialValue).SerializedType)
                    {
                        throw new ArgumentException(
                                  string.Format(
                                      "There is already an event metric definition for the same metrics system ({0}), category name ({1}), and counter name ({2}), but it is not compatible; " +
                                      "it defines value column \"{3}\" with type {4} rather than type {5}.",
                                      MetricTypeName, CategoryName, CounterName, ourValue.Name, officialValue.Type.Name, ourValue.Type.Name));
                    }
                }

                // We got through all the values defined in this instance?  Then we're okay to return the official one.
            }
            // Otherwise, it's just us, so we're all good.

            return(officialDefinition);
        }