Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs	(revision 5144)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs	(revision 5144)
@@ -0,0 +1,101 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Collections;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  public class ParameterCombinationsEnumerator : IEnumerator<IOptimizable> {
+    private IOptimizable node;
+    private List<IEnumerator> enumerators;
+    IEnumerator valueEnumerator;
+
+    public ParameterCombinationsEnumerator(IOptimizable node) {
+      this.node = node;
+      this.enumerators = new List<IEnumerator>();
+    }
+
+    public IOptimizable Current {
+      get { return node; }
+    }
+    object IEnumerator.Current {
+      get { return Current; }
+    }
+
+    public void Dispose() { }
+
+    public bool MoveNext() {
+      int i = 0;
+      bool ok = false;
+      while (!ok && i < enumerators.Count) {
+        if (enumerators[i].MoveNext()) {
+          ok = true;
+        } else {
+          i++;
+        }
+      }
+
+      if (ok) {
+        for (int k = i - 1; k >= 0; k--) {
+          enumerators[k].Reset();
+          enumerators[k].MoveNext();
+        }
+      } else {
+        return false;
+      }
+
+      var pc = node as IParameterConfiguration;
+      if (pc != null && valueEnumerator != null) {
+        pc.ActualValue = ((IValueConfiguration)valueEnumerator.Current).ActualValue;
+        pc.UpdateActualValueIndexToItem((IValueConfiguration)valueEnumerator.Current);
+      }
+      var vc = node as IValueConfiguration;
+      if (vc != null && valueEnumerator != null) {
+        vc.ActualValue.Value = (IItem)valueEnumerator.Current;
+      }
+      return true;
+    }
+
+    public void Reset() {
+      enumerators.Clear();
+      valueEnumerator = null;
+
+      var pc = node as IParameterConfiguration;
+      if (pc != null) {
+        valueEnumerator = pc.ValueConfigurations.CheckedItems.ToArray().GetEnumerator();
+        //valueEnumerator.Reset();
+        enumerators.Add(valueEnumerator);
+
+        foreach (var valueConfiguration in pc.ValueConfigurations.CheckedItems) {
+          if (valueConfiguration.Optimize) {
+            var enumerator = new ParameterCombinationsEnumerator(valueConfiguration);
+            enumerator.Reset();
+            enumerator.MoveNext();
+            enumerators.Add(enumerator);
+          }
+        }
+      }
+
+      var vc = node as IValueConfiguration;
+      if (vc != null) {
+        if (vc.RangeConstraint != null) {
+          valueEnumerator = vc.RangeConstraint.GetCombinations().ToArray().GetEnumerator();
+          //valueEnumerator.Reset();
+          //enumerator.MoveNext();
+          enumerators.Add(valueEnumerator);
+        } else {
+          foreach (var parameterConfiguration in vc.ParameterConfigurations) {
+            if (parameterConfiguration.Optimize) {
+              var enumerator = new ParameterCombinationsEnumerator(parameterConfiguration);
+              enumerator.Reset();
+              enumerator.MoveNext();
+              enumerators.Add(enumerator);
+            }
+          }
+        }
+      }
+    }
+
+  }
+}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs	(revision 5113)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs	(revision 5144)
@@ -8,9 +8,10 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Data;
+using System.Collections;
 
 namespace HeuristicLab.Problems.MetaOptimization {
   // todo: storable, name, descr, ...
   [StorableClass]
-  public class ParameterConfigurationTree : ValueConfiguration {
+  public class ParameterConfigurationTree : ValueConfiguration, IEnumerable {
     //[Storable]
     //public EngineAlgorithm Algorithm {
@@ -180,4 +181,29 @@
       ((IAlgorithm)item).CollectParameterValues(this.Parameters);
     }
+
+    public Experiment GenerateExperiment(IAlgorithm algorithm) {
+      Experiment experiment = new Experiment();
+      foreach (IValueConfiguration combination in this) {
+        IAlgorithm clonedAlg = (IAlgorithm)algorithm.Clone();
+        clonedAlg.Name = combination.ToParameterInfoString();
+        combination.Parameterize(clonedAlg);
+        experiment.Optimizers.Add(clonedAlg);
+      }
+      return experiment;
+    }
+
+    public IEnumerator GetEnumerator() {
+      IEnumerator enumerator = new ParameterCombinationsEnumerator(this);
+      enumerator.Reset();
+      return enumerator;
+    }
+
+    public long GetCombinationCount() {
+      long cnt = 0;
+      foreach (var c in this) {
+        cnt++;
+      }
+      return cnt;
+    }
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs	(revision 5113)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs	(revision 5144)
@@ -9,4 +9,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.PluginInfrastructure;
+using System.Text;
 
 namespace HeuristicLab.Problems.MetaOptimization {
@@ -299,4 +300,19 @@
     }
 
+    public string ToParameterInfoString() {
+      StringBuilder sb = new StringBuilder();
+      if (this.Optimize) {
+        sb.Append(string.Format("{0}: {1}", parameterName, this.ActualValue.Value));
+        //sb.Append(" (");
+        //var subParams = new List<string>();
+        //if (this.ActualValue.Value is IParameterizedItem) {
+        //  subParams.Add(this.ValueConfigurations.CheckedItems.ElementAt(actualValueConfigurationIndex).ToParameterInfoString());
+        //}
+        //sb.Append(string.Join(", ", subParams.ToArray()));
+        //sb.Append(")");
+      }
+      return sb.ToString();
+    }
+
     public static IParameterConfiguration Create(IParameterizedNamedItem parent, IParameter parameter) {
       if (parameter is IValueParameter) {
@@ -348,4 +364,14 @@
       }
     }
+
+    public void UpdateActualValueIndexToItem(IValueConfiguration vc) {
+      for (int i = 0; i < this.ValueConfigurations.CheckedItems.Count(); i++) {
+        if (this.ValueConfigurations.CheckedItems.ElementAt(i) == vc) {
+          this.actualValueConfigurationIndex = i;
+          return;
+        }
+      }
+    }
+
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/DoubleValueRange.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/DoubleValueRange.cs	(revision 5113)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/DoubleValueRange.cs	(revision 5144)
@@ -37,4 +37,17 @@
       if (value.Value < this.LowerBound.Value) value.Value = this.LowerBound.Value;
     }
+
+    public override IEnumerable<DoubleValue> GetCombinations() {
+      var solutions = new List<DoubleValue>();
+      double value = ((int)Math.Round(LowerBound.Value / StepSize.Value, 0)) * StepSize.Value;
+      if (value < LowerBound.Value) value += StepSize.Value;
+
+      while (value <= UpperBound.Value) {
+        //yield return new DoubleValue(value);
+        solutions.Add(new DoubleValue(value));
+        value += StepSize.Value;
+      }
+      return solutions;
+    }
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/IntValueRange.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/IntValueRange.cs	(revision 5113)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/IntValueRange.cs	(revision 5144)
@@ -37,4 +37,17 @@
       if (value.Value < this.LowerBound.Value) value.Value = this.LowerBound.Value;
     }
+
+    public override IEnumerable<IntValue> GetCombinations() {
+      var solutions = new List<IntValue>();
+      int value = (this.LowerBound.Value / StepSize.Value) * StepSize.Value;
+      if (value < this.LowerBound.Value) value += StepSize.Value;
+
+      while (value <= this.UpperBound.Value) {
+        //yield return new IntValue(value);
+        solutions.Add(new IntValue(value));
+        value += this.StepSize.Value;
+      }
+      return solutions;
+    }
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/PercentValueRange.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/PercentValueRange.cs	(revision 5113)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/PercentValueRange.cs	(revision 5144)
@@ -32,4 +32,17 @@
       return new DoubleValueRange(LowerBound, UpperBound, StepSize);
     }
+
+    public override IEnumerable<PercentValue> GetCombinations() {
+      var solutions = new List<PercentValue>();
+      double value = ((int)Math.Round(LowerBound.Value / StepSize.Value, 0)) * StepSize.Value;
+      if (value < LowerBound.Value) value += StepSize.Value;
+
+      while (value <= UpperBound.Value) {
+        //yield return new PercentValue(value);
+        solutions.Add(new PercentValue(value));
+        value += StepSize.Value;
+      }
+      return solutions;
+    }
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/Range.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/Range.cs	(revision 5113)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/Range.cs	(revision 5144)
@@ -1,3 +1,5 @@
 ﻿using System;
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -206,8 +208,12 @@
 
     protected abstract T GetRandomSample(IRandom random);
-
     IItem IRange.GetRandomValue(IRandom random) {
       return GetRandomValue(random);
     }
+
+    public abstract IEnumerable<T> GetCombinations();
+    IEnumerable<IItem> IRange.GetCombinations() {
+      return GetCombinations().Cast<IItem>().ToArray();
+    }
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs	(revision 5113)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs	(revision 5144)
@@ -9,4 +9,6 @@
 using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.PluginInfrastructure;
+using System.Collections.Generic;
+using System.Text;
 
 namespace HeuristicLab.Problems.MetaOptimization {
@@ -89,15 +91,14 @@
       this.IsOptimizable = true;
       if (actualValue.ValueDataType == typeof(IntValue)) {
-        rangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value, new IntValue(1));
+        RangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value, new IntValue(1));
       } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
-        rangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, new DoubleValue(0.01));
+        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, new DoubleValue(0.01));
       } else if (actualValue.ValueDataType == typeof(PercentValue)) {
-        rangeConstraint = new PercentValueRange(new PercentValue(0), new PercentValue(1), new PercentValue(0.001));
+        RangeConstraint = new PercentValueRange(new PercentValue(0), new PercentValue(1), new PercentValue(0.001));
       } else if (actualValue.ValueDataType == typeof(BoolValue)) {
         this.IsOptimizable = false; // there is nothing to configure for bools
       } else {
-        rangeConstraint = null;
-      }
-      RegisterRangeConstraintEvents();
+        RangeConstraint = null;
+      }
     }
 
@@ -155,5 +156,5 @@
     }
     #endregion
-    
+
     #region IItem Members
     public override string ItemDescription {
@@ -169,5 +170,5 @@
     }
     #endregion
-    
+
     #region Event Handlers
     public virtual event EventHandler ValueChanged;
@@ -208,4 +209,18 @@
         return base.ToString();
       }
+    }
+
+    public string ToParameterInfoString() {
+      StringBuilder sb = new StringBuilder();
+      if (this.Optimize) {
+        if (this.ParameterConfigurations.Count > 0) {
+          var parameterInfos = new List<string>();
+          foreach (var pc in this.ParameterConfigurations) {
+            if (pc.Optimize) parameterInfos.Add(pc.ToParameterInfoString());
+          }
+          sb.Append(string.Join(", ", parameterInfos.ToArray()));
+        }
+      }
+      return sb.ToString();
     }
 
