public IPredictionModel BuildModel(
            IDataFrame dataFrame,
            string dependentFeatureName,
            IModelBuilderParams additionalParams)
        {
            if (!(additionalParams is IDecisionTreeModelBuilderParams))
            {
                throw new ArgumentException("Invalid params passed for Decision Tree Model Builder!");
            }
            if (ShouldStopRecusrsiveBuilding(dataFrame, dependentFeatureName))
            {
                return BuildLeaf(dataFrame, dependentFeatureName);
            }

            var decisionTreeParams = (IDecisionTreeModelBuilderParams)additionalParams;
            var useParallelProcessing = decisionTreeParams.ProcessSubtreesCreationInParallel;
            var alreadyUsedAttributesInfo = new AlreadyUsedAttributesInfo();
            //TODO: reduce the number of parameters - maybe some nicer DTO?
            var node = this.BuildDecisionNode(dataFrame, dependentFeatureName, decisionTreeParams, alreadyUsedAttributesInfo, 0, useParallelProcessing);
            return node;
        }
        public IPredictionModel BuildModel(
            IDataFrame dataFrame,
            string dependentFeatureName,
            IModelBuilderParams additionalParams)
        {
            if (!(additionalParams is IDecisionTreeModelBuilderParams))
            {
                throw new ArgumentException("Invalid params passed for Decision Tree Model Builder!");
            }
            if (ShouldStopRecusrsiveBuilding(dataFrame, dependentFeatureName))
            {
                return(BuildLeaf(dataFrame, dependentFeatureName));
            }

            var decisionTreeParams        = (IDecisionTreeModelBuilderParams)additionalParams;
            var useParallelProcessing     = decisionTreeParams.ProcessSubtreesCreationInParallel;
            var alreadyUsedAttributesInfo = new AlreadyUsedAttributesInfo();
            //TODO: reduce the number of parameters - maybe some nicer DTO?
            var node = this.BuildDecisionNode(dataFrame, dependentFeatureName, decisionTreeParams, alreadyUsedAttributesInfo, 0, useParallelProcessing);

            return(node);
        }