/// <summary>
        /// Generates the the attribute.
        /// </summary>
        /// <param name="domainType">Type of the domain.</param>
        /// <param name="from">From.</param>
        /// <param name="to">To.</param>
        /// <param name="countOfCategories">The count of categories.</param>
        /// <param name="columnInfo">The column info.</param>
        /// <param name="boxIdentity">The box identity.</param>
        /// <returns>Generated attribute.</returns>
        public static GeneratedAttribute Generate(
			AttributeDomainEnum domainType,
			double from,
			double to,
			long countOfCategories,
			Ferda.Modules.Boxes.DataMiningCommon.Column.ColumnInfo columnInfo,
			string boxIdentity)
        {
            Ferda.Modules.Helpers.Data.Column.ValueType simpleColumnType = Ferda.Modules.Helpers.Data.Column.GetColumnValueTypeByValueSubType(columnInfo.columnSubType);
            if (simpleColumnType != Ferda.Modules.Helpers.Data.Column.ValueType.Integral
                && simpleColumnType != Ferda.Modules.Helpers.Data.Column.ValueType.Floating)
                throw Ferda.Modules.Exceptions.BadParamsError(null, boxIdentity, simpleColumnType.ToString(), restrictionTypeEnum.DbColumnDataType);

            //dataArray.Add(new Data(currentValue, currentCount));
            ArrayList dataArray = new ArrayList();
            DataTable frequencies = null;
            float startValue = Convert.ToSingle(columnInfo.statistics.ValueMin);
            float endValue = Convert.ToSingle(columnInfo.statistics.ValueMax);
            switch (domainType)
            {
                case AttributeDomainEnum.WholeDomain:
                    frequencies = Ferda.Modules.Helpers.Data.Column.GetDistinctsAndFrequencies(
                        columnInfo.dataMatrix.database.odbcConnectionString,
                        columnInfo.dataMatrix.dataMatrixName,
                        columnInfo.columnSelectExpression,
                        boxIdentity);
                    from = to = 0;
                    break;
                case AttributeDomainEnum.SubDomainValueBounds:
                    frequencies = Ferda.Modules.Helpers.Data.Column.GetDistinctsAndFrequencies(
                        columnInfo.dataMatrix.database.odbcConnectionString,
                        columnInfo.dataMatrix.dataMatrixName,
                        columnInfo.columnSelectExpression,
                        columnInfo.columnSelectExpression + ">=" + from + " AND " + columnInfo.columnSelectExpression + "<=" + to,
                        boxIdentity);
                    startValue = (float)from;
                    endValue = (float)to;
                    from = to = 0;
                    break;
                case AttributeDomainEnum.SubDomainNumberOfValuesBounds:
                    frequencies = Ferda.Modules.Helpers.Data.Column.GetDistinctsAndFrequencies(
                        columnInfo.dataMatrix.database.odbcConnectionString,
                        columnInfo.dataMatrix.dataMatrixName,
                        columnInfo.columnSelectExpression,
                        boxIdentity);
                    break;
                default:
                    throw Ferda.Modules.Exceptions.SwitchCaseNotImplementedError(domainType);
            }

            if (from < 0)
            {
                throw Ferda.Modules.Exceptions.BadValueError(null, boxIdentity, null, new string[] { "From" }, restrictionTypeEnum.Minimum);
            }
            if (to < 0)
            {
                throw Ferda.Modules.Exceptions.BadValueError(null, boxIdentity, null, new string[] { "To" }, restrictionTypeEnum.Minimum);
            }
            int fromUi = (int)from;
            int toUi = (int)to;
            int frequenciesCount = frequencies.Rows.Count;
            if (frequenciesCount <= from + to)
                return new GeneratedAttribute();
            object item;

            switch (simpleColumnType)
            {
                case Ferda.Modules.Helpers.Data.Column.ValueType.Floating:
                    for (int i = fromUi; i < (frequenciesCount - toUi); i++)
                    {
                        item = frequencies.Rows[i][Ferda.Modules.Helpers.Data.Column.SelectDistincts];
                        if (item == System.DBNull.Value)
                            continue;
                        dataArray.Add(new EquifrequencyIntervalGenerator.Data(Convert.ToSingle(item), Convert.ToInt32(frequencies.Rows[i][Ferda.Modules.Helpers.Data.Column.SelectFrequency])));
                    }
                    break;
                case Ferda.Modules.Helpers.Data.Column.ValueType.Integral:
                    for (int i = fromUi; i < (frequenciesCount - toUi); i++)
                    {
                        item = frequencies.Rows[i][Ferda.Modules.Helpers.Data.Column.SelectDistincts];
                        if (item == System.DBNull.Value)
                            continue;
                        dataArray.Add(new EquifrequencyIntervalGenerator.Data(Convert.ToInt64(item), Convert.ToInt32(frequencies.Rows[i][Ferda.Modules.Helpers.Data.Column.SelectFrequency])));
                    }
                    break;
                default:
                    throw Ferda.Modules.Exceptions.BadParamsError(null, boxIdentity, simpleColumnType.ToString(), restrictionTypeEnum.DbColumnDataType);
            }
            object[] splitPoints = null;
            try
            {
                splitPoints = EquifrequencyIntervalGenerator.GenerateIntervals((int)countOfCategories, dataArray);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                if (ex.ParamName == "intervals")
                {
                    throw Ferda.Modules.Exceptions.BadValueError(ex, boxIdentity, null, new string[] { "CountOfCategories" }, restrictionTypeEnum.Other);
                }
                else
                    throw ex;
            }
            if (splitPoints == null)
                return new GeneratedAttribute();

            CategoriesStruct categoriesStruct = new CategoriesStruct();

            string categoryName;
            List<SelectString> categoriesNames = new List<SelectString>();
            SelectString categoriesNamesItem;
            bool computeCategoriesNames = (splitPoints.Length + 1 < Ferda.Modules.Boxes.DataMiningCommon.Attributes.AbstractAttributeConstants.MaxLengthOfCategoriesNamesSelectStringArray);
            switch (simpleColumnType)
            {
                case Ferda.Modules.Helpers.Data.Column.ValueType.Floating:
                    categoriesStruct.floatIntervals = new FloatIntervalCategorySeq();
                    float beginValueFl = startValue;
                    float nextValueFl;
                    FloatIntervalStruct intervalFlTemplate = new FloatIntervalStruct();
                    intervalFlTemplate.leftBoundType = BoundaryEnum.Sharp;
                    intervalFlTemplate.rightBoundType = BoundaryEnum.Round;
                    FloatIntervalStruct intervalFl;
                    for (int i = 0; i < splitPoints.Length + 1; i++)
                    {
                        if (i == splitPoints.Length)
                        {
                            nextValueFl = endValue;
                            intervalFlTemplate.rightBoundType = BoundaryEnum.Sharp;
                        }
                        else
                            nextValueFl = (float)splitPoints[i];
                        intervalFl = intervalFlTemplate;
                        intervalFl.leftBound = beginValueFl;
                        intervalFl.rightBound = nextValueFl;
                        categoryName = Constants.LeftClosedInterval + beginValueFl.ToString() + Constants.SeparatorInterval + nextValueFl.ToString();
                        categoryName += (intervalFl.rightBoundType == BoundaryEnum.Sharp)? Constants.RightClosedInterval : Constants.RightOpenedInterval;

                        if (computeCategoriesNames)
                        {
                            categoriesNamesItem = new SelectString();
                            categoriesNamesItem.name = categoryName;
                            categoriesNamesItem.label = categoryName;
                            categoriesNames.Add(categoriesNamesItem);
                        }

                        categoriesStruct.floatIntervals.Add(
                            categoryName,
                            new FloatIntervalStruct[] { intervalFl });
                        beginValueFl = nextValueFl;
                    }

                    return new GeneratedAttribute(
                        categoriesStruct,
                        null,
                        categoriesStruct.floatIntervals.Count,
                        categoriesNames.ToArray());
                case Ferda.Modules.Helpers.Data.Column.ValueType.Integral:
                    categoriesStruct.longIntervals = new LongIntervalCategorySeq();
                    long beginValueLn = (long)startValue;
                    long nextValueLn;
                    LongIntervalStruct intervalLnTemplate = new LongIntervalStruct();
                    intervalLnTemplate.leftBoundType = BoundaryEnum.Sharp;
                    intervalLnTemplate.rightBoundType = BoundaryEnum.Round;
                    LongIntervalStruct intervalLn;
                    for (int i = 0; i < splitPoints.Length + 1; i++)
                    {
                        if (i == splitPoints.Length)
                        {
                            nextValueLn = (long)endValue;
                            intervalLnTemplate.rightBoundType = BoundaryEnum.Sharp;
                        }
                        else
                            nextValueLn = (long)splitPoints[i];
                        intervalLn = intervalLnTemplate;
                        intervalLn.leftBound = beginValueLn;
                        intervalLn.rightBound = nextValueLn;
                        categoryName = Constants.LeftClosedInterval + beginValueLn.ToString() + Constants.SeparatorInterval + nextValueLn.ToString();
                        categoryName += (intervalLn.rightBoundType == BoundaryEnum.Sharp)? Constants.RightClosedInterval : Constants.RightOpenedInterval;

                        if (computeCategoriesNames)
                        {
                            categoriesNamesItem = new SelectString();
                            categoriesNamesItem.name = categoryName;
                            categoriesNamesItem.label = categoryName;
                            categoriesNames.Add(categoriesNamesItem);
                        }

                        categoriesStruct.longIntervals.Add(
                            categoryName,
                            new LongIntervalStruct[] { intervalLn });
                        beginValueLn = nextValueLn;
                    }

                    return new GeneratedAttribute(
                        categoriesStruct,
                        null,
                        categoriesStruct.longIntervals.Count,
                        categoriesNames.ToArray());
                default:
                    throw Ferda.Modules.Exceptions.BadParamsError(null, boxIdentity, simpleColumnType.ToString(), restrictionTypeEnum.DbColumnDataType);
            }
        }
 /// <summary>
 /// It is strongly recommended to call this functions before calling any other function in this class.
 /// </summary>
 public GeneratedAttribute Value(string boxIdentity, BoxModuleI boxModule, ColumnInfo columnInfo, AttributeDomainEnum domainType, double from, double to, long countOfCategories)
 {
     lock (this)
     {
         Dictionary<string, IComparable> cacheSetting = new Dictionary<string, IComparable>();
         cacheSetting.Add(Database.DatabaseBoxInfo.typeIdentifier + Database.DatabaseBoxInfo.OdbcConnectionStringPropertyName, columnInfo.dataMatrix.database.odbcConnectionString);
         cacheSetting.Add(DataMatrix.DataMatrixBoxInfo.typeIdentifier + DataMatrix.DataMatrixBoxInfo.DataMatrixNamePropertyName, columnInfo.dataMatrix.dataMatrixName);
         cacheSetting.Add(DataMatrix.DataMatrixBoxInfo.typeIdentifier + DataMatrix.DataMatrixBoxInfo.RecordCountPropertyName, columnInfo.dataMatrix.recordsCount);
         cacheSetting.Add(Column.ColumnBoxInfo.typeIdentifier + Column.ColumnBoxInfo.ColumnSelectExpressionPropertyName, columnInfo.columnSelectExpression);
         cacheSetting.Add("DomainType", domainType);
         cacheSetting.Add("From", from);
         cacheSetting.Add("To", to);
         cacheSetting.Add("CountOfCategories", countOfCategories);
         if (IsObsolete(columnInfo.dataMatrix.database.lastReloadInfo, cacheSetting))
         {
             try
             {
                 value = EquidistantAlgorithm.Generate(
                     domainType,
                     from,
                     to,
                     countOfCategories,
                     columnInfo,
                     boxIdentity);
             }
             catch (Ferda.Modules.BadParamsError ex)
             {
                 value = new GeneratedAttribute();
                 if (ex.restrictionType == restrictionTypeEnum.DbColumnDataType)
                 {
                     boxModule.OutputMessage(
                         Ferda.ModulesManager.MsgType.Info,
                         "UnsupportedColumnDatatype",
                         "NumericDatatypesSupportedOnly");
                 }
                 else
                     throw Ferda.Modules.Exceptions.BoxRuntimeError(ex, boxModule.StringIceIdentity, null);
             }
         }
         if (value == null)
             value = new GeneratedAttribute();
         return value;
     }
 }
        /// <summary>
        /// Generates the attribute.
        /// </summary>
        /// <param name="domainType">Type of the domain.</param>
        /// <param name="from">From.</param>
        /// <param name="to">To.</param>
        /// <param name="closedFrom">The closed from.</param>
        /// <param name="length">The length.</param>
        /// <param name="column">The column.</param>
        /// <param name="boxIdentity">The box identity.</param>
        /// <returns>Generated attribute.</returns>
        public static GeneratedAttribute Generate(
            AttributeDomainEnum domainType,
            string from,
			string to,
			SidesEnum closedFrom,
			double length,
			ColumnInfo column,
			string boxIdentity)
        {
            if (length <= 0)
                throw Ferda.Modules.Exceptions.BadParamsError(null, boxIdentity, "Length have to be greater than 0!", restrictionTypeEnum.Minimum);

            DataTable distincts = null;

            //get from, to values
            switch (domainType)
            {
                case AttributeDomainEnum.WholeDomain:
                    from = column.statistics.ValueMin;
                    to = column.statistics.ValueMax;
                    break;
                case AttributeDomainEnum.SubDomainValueBounds:
                    break;
                case AttributeDomainEnum.SubDomainNumberOfValuesBounds:
                    int fromTmp, toTmp;
                    try
                    {
                        fromTmp = (String.IsNullOrEmpty(from)) ? 0 : Convert.ToInt32(from);
                    }
                    catch (System.ArgumentException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                    catch (System.OverflowException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                    catch (System.FormatException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                    try
                    {
                        toTmp = (String.IsNullOrEmpty(to)) ? 0 : Convert.ToInt32(to);
                    }
                    catch (System.ArgumentException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                    catch (System.OverflowException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                    catch (System.FormatException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                    distincts = Ferda.Modules.Helpers.Data.Column.GetDistincts(column.dataMatrix.database.odbcConnectionString, column.dataMatrix.dataMatrixName, column.columnSelectExpression, boxIdentity);
                    if (distincts.Rows.Count > fromTmp + toTmp)
                    {
                        from = distincts.Rows[fromTmp].ItemArray[0].ToString();
                        to = distincts.Rows[distincts.Rows.Count - toTmp - 1].ItemArray[0].ToString();
                    }
                    else
                    {
                        return new GeneratedAttribute();
                        //TODO ???
                    }
                    break;
                default:
                    throw Ferda.Modules.Exceptions.SwitchCaseNotImplementedError(domainType);
            }
            if (String.IsNullOrEmpty(from))
                from = column.statistics.ValueMin;
            if (String.IsNullOrEmpty(to))
                to = column.statistics.ValueMax;

            switch (Ferda.Modules.Helpers.Data.Column.GetColumnValueTypeByValueSubType(column.columnSubType))
            {
                case Ferda.Modules.Helpers.Data.Column.ValueType.Floating:
                    float fromTmpFl, toTmpFl;
                    try
                    {
                        fromTmpFl = (String.IsNullOrEmpty(from)) ? 0 : Convert.ToSingle(from);
                    }
                    catch (System.InvalidCastException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                    try
                    {
                        toTmpFl = (String.IsNullOrEmpty(to)) ? 0 : Convert.ToSingle(to);
                    }
                    catch (System.InvalidCastException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                    return generateFloating(fromTmpFl, toTmpFl, closedFrom, (float)length, column);
                case Ferda.Modules.Helpers.Data.Column.ValueType.Integral:
                    long fromTmpLn, toTmpLn;
                    try
                    {
                        fromTmpLn = (String.IsNullOrEmpty(from)) ? 0 : Convert.ToInt64(from);
                    }
                    catch (System.ArgumentException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                    catch (System.OverflowException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                    catch (System.FormatException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                    try
                    {
                        toTmpLn = (String.IsNullOrEmpty(to)) ? 0 : Convert.ToInt64(to);
                    }
                    catch (System.ArgumentException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                    catch (System.OverflowException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                    catch (System.FormatException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                    return generateIntegral(fromTmpLn, toTmpLn, closedFrom, (long)length, column);
                case Ferda.Modules.Helpers.Data.Column.ValueType.DateTime:
                    throw Ferda.Modules.Exceptions.BadParamsError(null, boxIdentity, null, restrictionTypeEnum.DbColumnDataType);
                //TODO
                /*
                DateTime fromTmpDt, toTmpDt;
                try
                {
                    fromTmpDt = Convert.ToDateTime(from);
                }
                catch (System.InvalidCastException ex) { throw badParamsError(boxIdentity, new string[] { "From" }, ex); }
                try
                {
                    toTmpDt = Convert.ToDateTime(to);
                }
                catch (System.InvalidCastException ex) { throw badParamsError(boxIdentity, new string[] { "To" }, ex); }
                return generateDateTime(fromTmpDt, toTmpDt, closedFrom, (long)length, column);
                 */
                case Ferda.Modules.Helpers.Data.Column.ValueType.String:
                    if (distincts == null)
                        distincts = Ferda.Modules.Helpers.Data.Column.GetDistincts(column.dataMatrix.database.odbcConnectionString, column.dataMatrix.dataMatrixName, column.columnSelectExpression, boxIdentity);
                    //TODO lepe distincts (dle from a to)
                    return generateString(from, to, (long)length, distincts);
                case Ferda.Modules.Helpers.Data.Column.ValueType.Boolean:
                    throw Ferda.Modules.Exceptions.BadParamsError(null, boxIdentity, null, restrictionTypeEnum.DbColumnDataType);
                //TODO
                //return generateBoolean(Convert.ToBoolean(from), Convert.ToBoolean(to), closedFrom, (long)length, column);
                case Ferda.Modules.Helpers.Data.Column.ValueType.Unknown:
                    //TODO
                    throw Ferda.Modules.Exceptions.BadParamsError(null, boxIdentity, null, restrictionTypeEnum.DbColumnDataType);
                default:
                    throw Ferda.Modules.Exceptions.SwitchCaseNotImplementedError(Ferda.Modules.Helpers.Data.Column.GetColumnValueTypeByValueSubType(column.columnSubType));
            }
        }