/// <summary>
 /// Create a new custom sampled metric object from the provided raw data packet
 /// </summary>
 /// <remarks>The new metric will automatically be added to the metric definition's metrics collection.</remarks>
 /// <param name="definition">The metric definition for the metric instance</param>
 /// <param name="packet">The raw data packet</param>
 internal CustomSampledMetric(CustomSampledMetricDefinition definition, CustomSampledMetricPacket packet)
     : base(definition, packet)
 {
     // We created a CustomSampledMetricSampleCollection when base constructor called our OnSampleCollectionCreate().
     m_Samples          = (CustomSampledMetricSampleCollection)base.Samples;
     m_MetricDefinition = definition;
     m_Packet           = packet;
 }
        /// <summary>
        /// Create an ordered array of all of the samples between the baseline sample and this one, inclusive
        /// </summary>
        /// <param name="baselineSample"></param>
        /// <returns></returns>
        private CustomSampledMetricSample[] SampleRange(CustomSampledMetricSample baselineSample)
        {
            CustomSampledMetricSample[] returnVal;

            //First, cheap trick:  Is the baseline and this sample the same?
            if (baselineSample == this)
            {
                //an array of one
                returnVal = new CustomSampledMetricSample[1];
                returnVal[0] = baselineSample;
                return returnVal;
            }

            //Now we need to check the real cases:  Find the first sample, find our sample, find everything in between.
            CustomSampledMetricSampleCollection samples = Metric.Samples;

            int baselineIndex = samples.IndexOf(baselineSample);
            int upperBoundIndex = samples.IndexOf(this);

            //we better have gotten values for both or this is bad
            if ((baselineIndex < 0) || (upperBoundIndex < 0))
            {
                throw new ArgumentOutOfRangeException(nameof(baselineSample), "Unable to use the provided baseline because either it or our sample are not in the same sample collection.");
            }

            if (baselineIndex > upperBoundIndex)
            {
                throw new ArgumentOutOfRangeException(nameof(baselineSample), "Unable to use the provided baseline because it is later than our sample in the samples collection, indicating they are in the wrong order.");
            }

            //If the upper bound index (which is our index) is before the end of the sample set, we want to include one more sample to handle
            //the time interval slide between the raw value and the metric sample (if any).
            if ((upperBoundIndex < (samples.Count - 1)) && (Packet.RawTimestamp != Timestamp))
            {
                //we want to include one more sample to be sure we get the whole time range
                upperBoundIndex++;
            }

            //Otherwise, we want to define our array to hold all of the necessary elements and then copy them.
            returnVal = new CustomSampledMetricSample[(upperBoundIndex - baselineIndex) + 1];

            for (int curSampleIndex = baselineIndex; curSampleIndex <= upperBoundIndex; curSampleIndex++)
            {
                returnVal[curSampleIndex - baselineIndex] = samples[curSampleIndex];
            }

            return returnVal;
        }