public void CategorySampleReadsDataCorrectly()
        {
            // ARRANGE
            var    dataList     = new List <byte>();
            string resourceName = "Unit.Tests.QuickPulse.PerfLib.PerfData.data";

            Stream stream = null;

            try
            {
                stream = typeof(CategorySampleTests).Assembly.GetManifestResourceStream(resourceName);

                using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                {
                    stream = null;

                    dataList.AddRange(reader.ReadToEnd().Split(',').Select(byte.Parse));
                }
            }
            finally
            {
                stream?.Dispose();
            }

            byte[] data = dataList.ToArray();

            var perfLib = PerfLib.GetPerfLib();

            // ACT
            var categorySample = new CategorySample(data, 230, 6, perfLib);

            // ASSERT
            // the test data has 28 counters, 165 instances, with the first counter being index 6 (% Processor Time).
            Assert.AreEqual(28, categorySample.CounterTable.Count);
            Assert.AreEqual(165, categorySample.InstanceNameTable.Count);
            Assert.AreEqual(6, categorySample.CounterTable.First().Key);
            Assert.AreEqual("Idle", categorySample.InstanceNameTable.First().Key);
        }
        /// <summary>
        /// Gets a collection of <see cref="QuickPulseProcess"/> objects - each corresponding to a system process and containing
        /// information about the amount of time the process has occupied CPU cores.
        /// </summary>
        /// <param name="totalTime">If available, contains the value of the _Total instance of the counter, which indicates the overall
        /// amount of time spent by CPU cores executing system processes.</param>
        public IEnumerable <QuickPulseProcess> GetProcesses(out TimeSpan?totalTime)
        {
            // "Process" object
            const int CategoryIndex = 230;

            // "% Processor Time" counter
            const int CounterIndex = 6;

            const string TotalInstanceName = "_Total";
            const string IdleInstanceName  = "Idle";

            CategorySample          categorySample = this.perfLib.GetCategorySample(CategoryIndex, CounterIndex);
            CounterDefinitionSample counterSample  = categorySample.CounterTable[CounterIndex];

            var procValues = new Dictionary <string, long>();

            foreach (var pair in categorySample.InstanceNameTable)
            {
                string instanceName = pair.Key;
                int    valueIndex   = pair.Value;

                long instanceValue = counterSample.GetInstanceValue(valueIndex);

                procValues.Add(instanceName, instanceValue);
            }

            long overallTime;

            totalTime = procValues.TryGetValue(TotalInstanceName, out overallTime) ? TimeSpan.FromTicks(overallTime) : (TimeSpan?)null;

            return
                (procValues.Where(
                     pv =>
                     !string.Equals(pv.Key, TotalInstanceName, StringComparison.Ordinal) &&
                     !string.Equals(pv.Key, IdleInstanceName, StringComparison.Ordinal))
                 .Select(pv => new QuickPulseProcess(pv.Key, TimeSpan.FromTicks(pv.Value))));
        }