/// <summary>
        /// Builds the consolidated column dictionary scanning all <see cref="imbSCI.Core.collection.PropertyCollectionExtended"/> items.
        /// </summary>
        /// <remarks>
        /// <para>If <c>__allowedColumns</c> are not specified it will include any newly column found inside collection</para>
        /// </remarks>
        /// <param name="obligatoryColumns">The obligatory columns.</param>
        /// <param name="__allowedColumns">The allowed columns.</param>
        /// <returns>Set of columns ready to be used for DataTable creation and for similar tasks</returns>
        public static PropertyEntryDictionary buildConsolidatedColumnDictionary(this IEnumerable <PropertyCollectionExtended> items, PropertyEntryColumn obligatoryColumns, object[] __allowedColumns = null)
        {
            List <PropertyEntryColumn> columnList = obligatoryColumns.getEnumListFromFlags <PropertyEntryColumn>();

            List <object> allowedColumns = __allowedColumns.getFlatList <object>();

            PropertyEntryDictionary output = new PropertyEntryDictionary();

            foreach (PropertyCollectionExtended pair in items)
            {
                foreach (object key in pair.Keys)
                {
                    if (!output.ContainsKey(key))
                    {
                        bool allowed = !allowedColumns.Any();
                        if (allowedColumns.Contains(key))
                        {
                            allowed = true;
                        }
                        if (allowed)
                        {
                            output.Add(key, pair.entries[key]);
                        }
                    }
                }
            }

            foreach (PropertyEntryColumn c in columnList)
            {
                if (!output.ContainsKey(c))
                {
                    PropertyEntry pe = new PropertyEntry(c, "", c.toColumnCaption(false), c.getDescriptionForKey());
                    output.Add(c, pe);
                }
            }

            //pel.Sort((x, y) => x.priority.CompareTo(y.priority));

            return(output);
        }
        /// <summary>
        /// Builds vertical datatable
        /// </summary>
        /// <param name="columns">The columns.</param>
        /// <param name="__title">The title.</param>
        /// <param name="__description">The description.</param>
        /// <param name="rows">The rows.</param>
        /// <returns></returns>
        public static DataTable buildDataTableVertical(this PropertyEntryDictionary columns, string __title, string __description = "", IEnumerable <PropertyCollection> rows = null)
        {
            var table = new DataTable();

            table.TableName = __title;

            //if (rows != null)
            //{
            //    autocount_format = rows.Count().getToStringDFormat(3);
            //}

            table.ExtendedProperties[templateFieldDataTable.data_tablename] = __title;
            table.ExtendedProperties[templateFieldDataTable.data_tabledesc] = __description;

            table.ExtendedProperties[templateFieldDataTable.shema_dictionary] = columns;

            //columns.Add(PropertyEntryColumn.autocount_idcolumn, new PropertyEntry(PropertyEntryColumn.autocount_idcolumn, 1, "ID", "Row number"));

            foreach (KeyValuePair <object, PropertyEntry> pair in columns)
            {
                DataColumn dc = table.Columns.Add();
                dc.ColumnName = pair.Value.keyName;
                //if (PropertyEntryColumn.autocount_idcolumn.ToString() == pair.Key.ToString())
                //{
                //    dc.AutoIncrementSeed = 1;
                //    dc.AutoIncrement = true;
                //    dc.AutoIncrementStep = 1;
                //    dc.DataType = typeof(Int32);
                //}

                dc.Caption       = pair.Value[PropertyEntryColumn.entry_name].toStringSafe();
                dc.ColumnMapping = MappingType.Element;
                dc.ExtendedProperties.AddRange(pair.Value);
            }

            table.addTableExtendedRows(rows, columns);
            return(table);
        }
        /// <summary>
        /// Builds the data table.
        /// </summary>
        /// <param name="shema">The shema.</param>
        /// <param name="__title">The title.</param>
        /// <param name="__description">The description.</param>
        /// <param name="rows">The rows.</param>
        /// <returns></returns>
        public static DataTable buildDataTableVertical(this PropertyCollectionExtended shema, string __title, string __description = "", IEnumerable <PropertyCollection> rows = null)
        {
            PropertyEntryDictionary columns = buildColumnDictionary(shema, PropertyEntryColumn.entry_name | PropertyEntryColumn.entry_value | PropertyEntryColumn.entry_description);

            return(columns.buildDataTableVertical(__title, __description, rows));
        }
        /// <summary>
        /// Adds the table extended rows.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <param name="rows">The rows.</param>
        /// <param name="columns">The columns.</param>
        /// <exception cref="System.ArgumentNullException">columns - Column shema never supplied -- and the table has no shema attached on templateFieldDataTable.shema_dictionary</exception>
        public static void addTableExtendedRows(this DataTable table, IEnumerable <PropertyCollection> rows, PropertyEntryDictionary columns = null)
        {
            if (columns == null)
            {
                if (table.ExtendedProperties.ContainsKey(templateFieldDataTable.shema_dictionary))
                {
                    columns = (PropertyEntryDictionary)table.ExtendedProperties[templateFieldDataTable.shema_dictionary];
                }
            }

            //String autocount_format = "D3";

            //if (table.ExtendedProperties.ContainsKey(templateFieldDataTable.count_format))
            //{
            //    autocount_format = (String)table.ExtendedProperties[templateFieldDataTable.count_format];
            //}
            //autocount_format = rows.Count().getToStringDFormat(3);

            if (columns == null)
            {
                throw new ArgumentNullException("columns", "Column shema never supplied -- and the table has no shema attached on templateFieldDataTable.shema_dictionary");
            }
            if (rows == null)
            {
                return;
            }
            int c = 1;

            foreach (PropertyCollectionExtended pce in rows)
            {
                DataRow dr = table.NewRow();
                object  vl = getColumnValue_Default;

                foreach (KeyValuePair <object, PropertyEntry> pair in columns)
                {
                    dr[(string)pair.Value.keyName] = getColumnValue(pair.Value, pce, c, "D4");
                }

                table.Rows.Add(dr);
                c++;
            }
        }
        /// <summary>
        /// Builds the data table - from all entries inside the collection
        /// </summary>
        /// <param name="columns">The columns.</param>
        /// <returns>DataTable ready for output</returns>
        public static DataTable buildDataTableHorizontal(this IEnumerable <PropertyCollectionExtended> items, string name, string description, PropertyEntryDictionary columns = null)
        {
            DataTable output = new DataTable();

            if (columns == null)
            {
                // columns = buildConsolidatedColumnDictionary(PropertyEntryColumn.entry_name | PropertyEntryColumn.entry_value | PropertyEntryColumn.entry_description);
                columns = items.buildConsolidatedColumnDictionary(PropertyEntryColumn.entry_name | PropertyEntryColumn.entry_value | PropertyEntryColumn.entry_description);
            }

            output.TableName = name;
            output.ExtendedProperties[templateFieldDataTable.data_tablename]     = name;
            output.ExtendedProperties[templateFieldDataTable.data_tabledesc]     = description;
            output.ExtendedProperties[templateFieldDataTable.data_rowcounttotal] = items.Count();

            output.ExtendedProperties[templateFieldDataTable.shema_sourceinstance] = columns.GetType().Name;

            //columns.Values.ToList()

            foreach (KeyValuePair <object, PropertyEntry> pair in columns)
            {
                DataColumn dc = output.Columns.Add();
                dc.ColumnName = pair.Value.keyName;

                dc.Caption       = pair.Value[PropertyEntryColumn.entry_name].toStringSafe();
                dc.ColumnMapping = MappingType.Element;
                dc.ExtendedProperties.AddRange(pair.Value);
            }

            string autocount_format = items.Count().getToStringDFormat(2);

            int c = 1;

            if (items == null)
            {
                return(output);
            }
            else
            {
            }
            foreach (PropertyCollectionExtended pce in items)
            {
                DataRow dr = output.NewRow();
                object  vl = "--";

                foreach (KeyValuePair <object, PropertyEntry> pair in columns)
                {
                    dr[(string)pair.Value.keyName] = getColumnValue(pair.Value, pce, c, autocount_format);
                }

                output.Rows.Add(dr);
                c++;
            }

            return(output);
        }
        ///// <summary>
        ///// Builds the category property list via measures.
        ///// </summary>
        ///// <param name="source">The source.</param>
        ///// <param name="name">The name.</param>
        ///// <param name="description">The description.</param>
        ///// <returns></returns>
        //public static PropertyCollectionExtendedList buildCategoryPropertyListViaMeasures(this Type source, String name, String description)
        //{
        //    String __name = source.getAttributeValueOrDefault<DisplayNameAttribute>(name, false);
        //    String __description = source.getAttributeValueOrDefault<DisplayNameAttribute>(description, false);
        //    measureSetExternal setExternal = new measureSetExternal(source, __name, __description);

        //    return setExternal.export();
        //}

        /// <summary>
        /// Builds vertical data table - aka: comparative table
        /// </summary>
        /// <param name="items">The items.</param>
        /// <param name="name">The name.</param>
        /// <param name="description">The description.</param>
        /// <param name="columns">The columns.</param>
        /// <returns></returns>
        public static DataTable buildComparativeDataTable(this IEnumerable <PropertyCollectionExtended> items, string itemNameProperty, string name, string description, PropertyEntryDictionary columns = null)
        {
            DataTable output = items.buildDataTableHorizontal(name, description, columns);

            output = output.GetInversedDataTable(itemNameProperty);

            return(output);
        }