/// <summary>
        /// Given a predictor type returns a set of all permissible learners (with their sweeper params, if defined).
        /// </summary>
        /// <returns>Array of viable learners.</returns>
        public static SuggestedRecipe.SuggestedLearner[] AllowedLearners(IHostEnvironment env, MacroUtils.TrainerKinds trainerKind)
        {
            //not all learners advertised in the API are available in CORE.
            var catalog = ModuleCatalog.CreateInstance(env);
            var availableLearnersList = catalog.AllEntryPoints().Where(
                x => x.InputKinds?.FirstOrDefault(i => i == typeof(CommonInputs.ITrainerInput)) != null);

            var learners     = new List <SuggestedRecipe.SuggestedLearner>();
            var type         = typeof(CommonInputs.ITrainerInput);
            var trainerTypes = typeof(Experiment).Assembly.GetTypes()
                               .Where(p => type.IsAssignableFrom(p) &&
                                      MacroUtils.IsTrainerOfKind(p, trainerKind));

            foreach (var tt in trainerTypes)
            {
                var sweepParams = AutoMlUtils.GetSweepRanges(tt);
                var epInputObj  = (CommonInputs.ITrainerInput)tt.GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { });
                var sl          = new SuggestedRecipe.SuggestedLearner
                {
                    PipelineNode = new TrainerPipelineNode(epInputObj, sweepParams),
                    LearnerName  = tt.Name
                };

                if (sl.PipelineNode != null && availableLearnersList.FirstOrDefault(l => l.Name.Equals(sl.PipelineNode.GetEpName())) != null)
                {
                    learners.Add(sl);
                }
            }

            return(learners.ToArray());
        }
            protected override IEnumerable <SuggestedRecipe> ApplyCore(Type predictorType,
                                                                       TransformInference.SuggestedTransform[] transforms)
            {
                SuggestedRecipe.SuggestedLearner learner = new SuggestedRecipe.SuggestedLearner();
                learner.LoadableClassInfo =
                    ComponentCatalog.GetLoadableClassInfo <SignatureTrainer>(Learners.MultiClassNaiveBayesTrainer.LoadName);
                learner.Settings = "";
                var epInput = new Legacy.Trainers.NaiveBayesClassifier();

                learner.PipelineNode = new TrainerPipelineNode(epInput);
                yield return(new SuggestedRecipe(ToString(), transforms, new[] { learner }));
            }
            protected override IEnumerable <SuggestedRecipe> ApplyCore(Type predictorType,
                                                                       TransformInference.SuggestedTransform[] transforms)
            {
                SuggestedRecipe.SuggestedLearner learner = new SuggestedRecipe.SuggestedLearner();
                if (predictorType == typeof(SignatureMultiClassClassifierTrainer))
                {
                    learner.LoadableClassInfo =
                        ComponentCatalog.GetLoadableClassInfo <SignatureTrainer>(Learners.SdcaMultiClassTrainer.LoadNameValue);
                }
                else
                {
                    learner.LoadableClassInfo =
                        ComponentCatalog.GetLoadableClassInfo <SignatureTrainer>(Learners.LinearClassificationTrainer.LoadNameValue);
                    var epInput = new Legacy.Trainers.StochasticDualCoordinateAscentBinaryClassifier();
                    learner.PipelineNode = new TrainerPipelineNode(epInput);
                }

                learner.Settings = "";
                yield return(new SuggestedRecipe(ToString(), transforms, new[] { learner }));
            }
            protected override IEnumerable <SuggestedRecipe> ApplyCore(Type predictorType,
                                                                       TransformInference.SuggestedTransform[] transforms)
            {
                SuggestedRecipe.SuggestedLearner learner = new SuggestedRecipe.SuggestedLearner();
                if (predictorType == typeof(SignatureMultiClassClassifierTrainer))
                {
                    learner.LoadableClassInfo = Host.ComponentCatalog.GetLoadableClassInfo <SignatureTrainer>("OVA");
                    learner.Settings          = "p=FastTreeBinaryClassification";
                }
                else
                {
                    learner.LoadableClassInfo =
                        Host.ComponentCatalog.GetLoadableClassInfo <SignatureTrainer>(FastTreeBinaryClassificationTrainer.LoadNameValue);
                    learner.Settings = "";
                    var epInput = new Legacy.Trainers.FastTreeBinaryClassifier();
                    learner.PipelineNode = new TrainerPipelineNode(epInput);
                }

                yield return(new SuggestedRecipe(ToString(), transforms, new[] { learner }));
            }
            protected override IEnumerable <SuggestedRecipe> ApplyCore(Type predictorType,
                                                                       TransformInference.SuggestedTransform[] transforms)
            {
                SuggestedRecipe.SuggestedLearner learner = new SuggestedRecipe.SuggestedLearner();
                if (predictorType == typeof(SignatureMultiClassClassifierTrainer))
                {
                    learner.LoadableClassInfo = ComponentCatalog.GetLoadableClassInfo <SignatureTrainer>("OVA");
                    learner.Settings          = "p=AveragedPerceptron{iter=10}";
                }
                else
                {
                    learner.LoadableClassInfo = ComponentCatalog.GetLoadableClassInfo <SignatureTrainer>(Learners.AveragedPerceptronTrainer.LoadNameValue);
                    learner.Settings          = "iter=10";
                    var epInput = new Legacy.Trainers.AveragedPerceptronBinaryClassifier
                    {
                        NumIterations = 10
                    };
                    learner.PipelineNode = new TrainerPipelineNode(epInput);
                }

                yield return
                    (new SuggestedRecipe(ToString(), transforms, new[] { learner }, Int32.MaxValue));
            }