// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/constraints/FeatureConstraint.java
// @Entity
// @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
// public abstract class FeatureConstraint {
// 
//     @Id
//     @GeneratedValue(strategy = GenerationType.SEQUENCE)
//     Long id;
// 
//     @ManyToOne
//     Product forProduct;
// 
//     public abstract String getType();
// 
//     public abstract EvaluationResult evaluateConfiguration(EvaluationResult currentResult, ProductConfiguration configuration);
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public void setForProduct(Product forProduct) {
//         this.forProduct = forProduct;
//     }
// }


import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.constraints.FeatureConstraint;
import org.springframework.stereotype.Component;
import java.util.Set;
package org.javiermf.features.models.evaluation;



@Component
public class ConfigurationEvaluator {


    public EvaluationResult evaluateConfiguration(ProductConfiguration configuration, Set<FeatureConstraint> featureConstraints) {
        EvaluationResult result = new EvaluationResult();
        result = addEvaluationsToResult(result, configuration, featureConstraints);

        return result;
    }

// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/constraints/FeatureConstraint.java
// @Entity
// @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
// public abstract class FeatureConstraint {
// 
//     @Id
//     @GeneratedValue(strategy = GenerationType.SEQUENCE)
//     Long id;
// 
//     @ManyToOne
//     Product forProduct;
// 
//     public abstract String getType();
// 
//     public abstract EvaluationResult evaluateConfiguration(EvaluationResult currentResult, ProductConfiguration configuration);
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public void setForProduct(Product forProduct) {
//         this.forProduct = forProduct;
//     }
// }


// Path: src/main/java/org/javiermf/features/models/evaluation/ConfigurationEvaluator.java
import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.constraints.FeatureConstraint;
import org.springframework.stereotype.Component;
import java.util.Set;

package org.javiermf.features.models.evaluation;



@Component
public class ConfigurationEvaluator {


    public EvaluationResult evaluateConfiguration(ProductConfiguration configuration, Set<FeatureConstraint> featureConstraints) {
        EvaluationResult result = new EvaluationResult();
        result = addEvaluationsToResult(result, configuration, featureConstraints);

        return result;
    }

    private EvaluationResult addEvaluationsToResult(EvaluationResult result, ProductConfiguration configuration, Set<FeatureConstraint> featureConstraints) {