public new void Add(string key, collectionAggregationResult <T> result)
        {
            Count += result.Count;
            type   = result.type;
            aspect = result.aspect;

            if (firstItem == null)
            {
                firstItem = result.firstItem;
            }
            lastItem = result.lastItem;
            base.Add(key, result);
        }
        /// <summary>
        /// Gets aggregated version of the objects
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">The source.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static collectionAggregationResult <T> GetAggregates <T>(this IEnumerable <T> source, dataPointAggregationType type = dataPointAggregationType.avg, bool stringKeepLastEntry = true) where T : class, new()
        {
            //if (type == dataPointAggregationType.none)
            //{
            //}

            var aggList = type.getEnumListFromFlags <dataPointAggregationType>();

            collectionAggregationResult <T> output = new collectionAggregationResult <T>();

            output.aspect = dataPointAggregationAspect.subSetOfRows;

            aceDictionary2D <dataPointAggregationType, PropertyInfo, double> outputData = new aceDictionary2D <dataPointAggregationType, PropertyInfo, double>();

            aceDictionary2D <dataPointAggregationType, PropertyInfo, List <double> > datatCollections = new aceDictionary2D <dataPointAggregationType, PropertyInfo, List <double> >();

            Type t = typeof(T);

            List <PropertyInfo> nominalList = new List <PropertyInfo>();
            List <PropertyInfo> piList      = new List <PropertyInfo>();

            Dictionary <PropertyInfo, settingsPropertyEntry> sPEDict = new Dictionary <PropertyInfo, settingsPropertyEntry>();

            foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty | BindingFlags.GetProperty))
            {
                settingsPropertyEntry sPE = new settingsPropertyEntry(pi);

                bool ok = true;

                if (!pi.CanWrite)
                {
                    ok = false;
                }

                if (ok && pi.PropertyType == typeof(string))
                {
                    nominalList.Add(pi);
                    ok = false;
                }
                else if (ok && pi.PropertyType == typeof(Enum))
                {
                    ok = false;
                }

                if (ok && sPE.aggregation[dataPointAggregationAspect.subSetOfRows].HasFlag(dataPointAggregationType.hidden))
                {
                    ok = false;
                }
                if (ok && sPE.attributes.ContainsKey(imbAttributeName.reporting_hide))
                {
                    ok = false;
                }

                if (ok)
                {
                    sPEDict.Add(pi, sPE);
                    piList.Add(pi);
                }
            }

            if (aggList.Contains(dataPointAggregationType.avg))
            {
                aggList.AddUnique(dataPointAggregationType.sum);
            }

            if (aggList.Contains(dataPointAggregationType.range))
            {
                aggList.AddUnique(dataPointAggregationType.min);
                aggList.AddUnique(dataPointAggregationType.max);
            }

            foreach (dataPointAggregationType aggType in aggList)
            {
                output.Add(aggType, new T());

                switch (aggType)
                {
                case dataPointAggregationType.var:
                case dataPointAggregationType.stdev:
                case dataPointAggregationType.entropy:
                    foreach (PropertyInfo pi in piList)
                    {
                        datatCollections[aggType, pi] = new List <double>();    //.Add(item.imbGetPropertySafe<Double>(pi));
                    }
                    break;
                }

                // outputData.Add(aggType, 0);
            }

            int count = 0;

            // <------------ first pass
            foreach (T item in source)
            {
                if (output.firstItem == null)
                {
                    output.firstItem = item;
                }
                output.lastItem = item;
                foreach (dataPointAggregationType aggType in aggList)
                {
                    foreach (PropertyInfo pi in piList)
                    {
                        double vl = outputData[aggType, pi];

                        switch (aggType)
                        {
                        case dataPointAggregationType.sum:
                            vl = vl + item.imbGetPropertySafe <double>(pi);
                            break;

                        case dataPointAggregationType.min:
                            vl = Math.Min(item.imbGetPropertySafe <double>(pi), vl);
                            break;

                        case dataPointAggregationType.max:
                            vl = Math.Max(item.imbGetPropertySafe <double>(pi), vl);
                            break;

                        case dataPointAggregationType.var:
                        case dataPointAggregationType.stdev:
                        case dataPointAggregationType.entropy:
                            datatCollections[aggType, pi].Add(item.imbGetPropertySafe <double>(pi));
                            break;
                        }
                        outputData[aggType, pi] = vl;
                    }
                }

                count++;
            }

            foreach (dataPointAggregationType aggType in aggList)
            {
                foreach (PropertyInfo pi in piList)
                {
                    switch (aggType)
                    {
                    case dataPointAggregationType.count:
                        outputData[aggType, pi] = count;
                        break;

                    case dataPointAggregationType.avg:
                        outputData[aggType, pi] = outputData[dataPointAggregationType.sum, pi] / (double)count;
                        break;

                    case dataPointAggregationType.range:
                        outputData[aggType, pi] = outputData[dataPointAggregationType.max, pi] - outputData[dataPointAggregationType.min, pi];
                        break;

                    case dataPointAggregationType.firstEntry:
                        outputData[aggType, pi] = output.firstItem.imbGetPropertySafe <double>(pi);
                        break;

                    case dataPointAggregationType.lastEntry:
                        outputData[aggType, pi] = output.lastItem.imbGetPropertySafe <double>(pi);
                        break;

                    case dataPointAggregationType.var:
                        outputData[aggType, pi] = datatCollections[aggType, pi].GetVariance();
                        break;

                    case dataPointAggregationType.stdev:
                        outputData[aggType, pi] = datatCollections[aggType, pi].GetStdDeviation();
                        break;

                    case dataPointAggregationType.entropy:
                        outputData[aggType, pi] = datatCollections[aggType, pi].GetEntropy();
                        break;
                    }
                }
            }

            foreach (dataPointAggregationType aggType in aggList)
            {
                foreach (PropertyInfo pi in piList)
                {
                    output[aggType].imbSetPropertyConvertSafe(pi, outputData[aggType, pi]);
                }

                if (stringKeepLastEntry)
                {
                    foreach (PropertyInfo pi in nominalList)
                    {
                        output[aggType].imbSetPropertyConvertSafe(pi, output.lastItem.imbGetPropertySafe(pi));
                    }
                }
            }
            output.Count = count;
            return(output);
        }