/// <summary>
        /// Computes the average of each "feature"
        /// </summary>
        public static IArray<double> Averages(this IEnumerable<IEnumerable<double>> data)
        {
            var sums = new List<double>(data.First());
            int count = 1, i;
            foreach (var enumerable in data.Skip(1))
            {
                count++;
                i = 0;
                foreach (double d in enumerable)
                    if (sums.Count <= i)
                        break;
                    else
                        sums[i++] += d;
                for (int j = sums.Count - 1; j >= i; j--)
                    sums.RemoveAt(j);
            }

            for (i = 0; i < sums.Count; i++)
                sums[i] /= count;

            return sums.AsIArray();
        }
        /// <summary>
        /// Groups entries using the sequences formed by their relative timestamps
        /// </summary>
        public static IEnumerable<IArrayView<EEGDataEntry>> SectionByStimulus(this IEnumerable<EEGDataEntry> entries)
        {
            if (entries.IsEmpty())
                yield break;

            var section = new List<EEGDataEntry>() { entries.First() };
            foreach (var entry in entries.Skip(1))
            {
                if (entry.RelativeTimeStamp >= section.LastItem().RelativeTimeStamp)
                    section.Add(entry);
                else
                {
                    yield return section.AsIArray();
                    section = new List<EEGDataEntry>() { entry };
                }
            }

            yield return section.AsIArray(); // return the last section
        }
        /// <summary>
        /// Groups the entries by their respective time bins
        /// </summary>
        public static IArrayView<IArrayView<EEGDataEntry>> BinByTime(this IEnumerable<EEGDataEntry> entries, int binWidthMillis)
        {
            if (binWidthMillis <= 0)
                throw new ArgumentOutOfRangeException("binWidthMillis");

            int baseTime = entries.First().TimeStamp;
            var bins = new List<IArrayView<EEGDataEntry>>();
            var bin = new List<EEGDataEntry>();
            foreach (var entry in entries)
                // add it the the current bin
                if (entry.TimeStamp < baseTime + binWidthMillis)
                    bin.Add(entry);
                else // save the old bin and add it to the new one
                {
                    bins.Add(bin.AsIArray());

                    while (true)
                    {
                        baseTime += binWidthMillis;
                        if (entry.TimeStamp < baseTime + binWidthMillis)
                        {
                            bin = new List<EEGDataEntry>() { entry };
                            break;
                        }

                        bins.Add(Arrays.New<EEGDataEntry>(0)); // empty array
                    }
                }

            // make sure to get the last bin!
            if (bin.Count > 0)
                bins.Add(bin.AsIArray());

            return bins.AsIArray();
        }