// 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/evaluation/EvaluationResult.java
// public class EvaluationResult {
// 
//     public boolean isValid = true;
// 
//     public Set<String> derivedFeatures = new HashSet<String>();
// 
//     public Set<String> evaluationErrorMessages = new HashSet<String>();
// 
// 
// }


import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.evaluation.EvaluationResult;
import javax.persistence.Basic;
import javax.persistence.Entity;
        this.excludedFeatureName = excludedFeatureName;
    }

    @Override
    public String getType() {
        return "excludes";
    }

    @Override
    public EvaluationResult evaluateConfiguration(EvaluationResult currentResult, ProductConfiguration configuration) {
        if (configuration.hasActiveFeature(sourceFeatureName) &&
                configuration.hasActiveFeature(excludedFeatureName)) {
            currentResult.isValid = false;
            currentResult.evaluationErrorMessages.add(String.format("Feauture %s can not be active when feature %s is active", excludedFeatureName, sourceFeatureName));
        }
        return currentResult;
    }

    public String getSourceFeatureName() {
        return sourceFeatureName;
    }

    public void setSourceFeatureName(String sourceFeatureName) {
        this.sourceFeatureName = sourceFeatureName;
    }

    public String getExcludedFeatureName() {
        return excludedFeatureName;
    }

// 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/evaluation/EvaluationResult.java
// public class EvaluationResult {
// 
//     public boolean isValid = true;
// 
//     public Set<String> derivedFeatures = new HashSet<String>();
// 
//     public Set<String> evaluationErrorMessages = new HashSet<String>();
// 
// 
// }


// Path: src/main/java/org/javiermf/features/models/constraints/ConstraintExcludes.java
import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.evaluation.EvaluationResult;
import javax.persistence.Basic;
import javax.persistence.Entity;

        this.excludedFeatureName = excludedFeatureName;
    }

    @Override
    public String getType() {
        return "excludes";
    }

    @Override
    public EvaluationResult evaluateConfiguration(EvaluationResult currentResult, ProductConfiguration configuration) {
        if (configuration.hasActiveFeature(sourceFeatureName) &&
                configuration.hasActiveFeature(excludedFeatureName)) {
            currentResult.isValid = false;
            currentResult.evaluationErrorMessages.add(String.format("Feauture %s can not be active when feature %s is active", excludedFeatureName, sourceFeatureName));
        }
        return currentResult;
    }

    public String getSourceFeatureName() {
        return sourceFeatureName;
    }

    public void setSourceFeatureName(String sourceFeatureName) {
        this.sourceFeatureName = sourceFeatureName;
    }

    public String getExcludedFeatureName() {
        return excludedFeatureName;
    }

    public void setExcludedFeatureName(String excludedFeatureName) {