Index: trunk/sources/HeuristicLab.GP.Boolean/3.3/BooleanTreeInterpreter.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.Boolean/3.3/BooleanTreeInterpreter.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.GP.Boolean/3.3/BooleanTreeInterpreter.cs	(revision 2174)
@@ -67,5 +67,5 @@
         case SymbolTable.NOR: return !(Step() | Step());
         case SymbolTable.VARIABLE:
-          return dataset.GetValue(currentRow, (int)curFun.data[0]) != 0.0;
+          return dataset.GetValue(currentRow, (int)curFun.localData[0]) != 0.0;
         case SymbolTable.UNKNOWN:
         default:
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/Constant.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/Constant.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/Constant.cs	(revision 2174)
@@ -41,5 +41,5 @@
     public Constant()
       : base() {
-      AddVariableInfo(new VariableInfo(VALUE, "The constant value", typeof(ConstrainedDoubleData), VariableKind.None));
+      AddVariableInfo(new VariableInfo(VALUE, "The constant value", typeof(DoubleData), VariableKind.None));
       GetVariableInfo(VALUE).Local = true;
 
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/FunctionLibraryInjector.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/FunctionLibraryInjector.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/FunctionLibraryInjector.cs	(revision 2174)
@@ -32,5 +32,4 @@
 namespace HeuristicLab.GP.StructureIdentification {
   public class FunctionLibraryInjector : OperatorBase {
-    private const string NUMBEROFINPUTVARIABLES = "NumberOfInputVariables";
     private const string FUNCTIONLIBRARY = "FunctionLibrary";
     private const string TARGETVARIABLE = "TargetVariable";
@@ -70,5 +69,4 @@
     public FunctionLibraryInjector()
       : base() {
-      AddVariableInfo(new VariableInfo(NUMBEROFINPUTVARIABLES, "The number of available input variables", typeof(IntData), VariableKind.In));
       AddVariableInfo(new VariableInfo(TARGETVARIABLE, "The target variable", typeof(IntData), VariableKind.In));
       AddVariableInfo(new VariableInfo(MINTIMEOFFSET, "Minimal time offset for all features", typeof(IntData), VariableKind.In));
@@ -111,5 +109,4 @@
       StructId.Variable variable;
       GPOperatorLibrary operatorLibrary;
-      int nInputVariables = GetVariableValue<IntData>(NUMBEROFINPUTVARIABLES, scope, true).Data;
       int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
 
@@ -225,6 +222,6 @@
       ConditionalAddOperator(XOR_ALLOWED, operatorLibrary, xor);
 
-      variable.SetConstraints(1, nInputVariables, minTimeOffset, maxTimeOffset);
-      differential.SetConstraints(1, nInputVariables, minTimeOffset, maxTimeOffset);
+      variable.SetConstraints(minTimeOffset, maxTimeOffset);
+      differential.SetConstraints(minTimeOffset, maxTimeOffset);
 
       scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName(FUNCTIONLIBRARY), operatorLibrary));
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/ModelAnalyzerExporter.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/ModelAnalyzerExporter.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/ModelAnalyzerExporter.cs	(revision 2174)
@@ -196,5 +196,5 @@
         weight = ((DoubleData)weightItem).Data;
       }
-      double index = ((ConstrainedIntData)tree.GetLocalVariable(Variable.INDEX).Value).Data;
+      string index = ((StringData)tree.GetLocalVariable(Variable.INDEX).Value).Data;
       double offset = ((ConstrainedIntData)tree.GetLocalVariable(Variable.OFFSET).Value).Data;
 
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/TreeEvaluatorBase.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/TreeEvaluatorBase.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/TreeEvaluatorBase.cs	(revision 2174)
@@ -78,11 +78,11 @@
         case EvaluatorSymbolTable.DIFFERENTIAL:
         case EvaluatorSymbolTable.VARIABLE: {
-            instr.i_arg0 = (short)f.data[0]; // var
-            instr.d_arg0 = f.data[1]; // weight
-            instr.i_arg1 = (short)f.data[2]; // sample-offset
+            instr.i_arg0 = (short)dataset.GetVariableIndex((string)f.localData[0]); // var
+            instr.d_arg0 = (double)f.localData[1]; // weight
+            instr.i_arg1 = (short)(int)f.localData[2]; // sample-offset
             break;
           }
         case EvaluatorSymbolTable.CONSTANT: {
-            instr.d_arg0 = f.data[0]; // value
+            instr.d_arg0 = (double)f.localData[0]; // value
             break;
           }
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/Variable.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/Variable.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/Variable.cs	(revision 2174)
@@ -38,6 +38,4 @@
     public const string INDEX = "Variable";
 
-    private int minIndex;
-    private int maxIndex;
     private int minOffset;
     private int maxOffset;
@@ -53,7 +51,7 @@
     public Variable()
       : base() {
-      AddVariableInfo(new VariableInfo(INDEX, "Index of the variable in the dataset representing this feature", typeof(ConstrainedIntData), VariableKind.None));
+      AddVariableInfo(new VariableInfo(INDEX, "The variable name", typeof(StringData), VariableKind.None));
       GetVariableInfo(INDEX).Local = true;
-      AddVariableInfo(new VariableInfo(WEIGHT, "Weight is multiplied to the feature value", typeof(ConstrainedDoubleData), VariableKind.None));
+      AddVariableInfo(new VariableInfo(WEIGHT, "Weight is multiplied to the feature value", typeof(DoubleData), VariableKind.None));
       GetVariableInfo(WEIGHT).Local = true;
       AddVariableInfo(new VariableInfo(OFFSET, "SampleOffset is added to the sample index", typeof(ConstrainedIntData), VariableKind.None));
@@ -67,7 +65,6 @@
       AddVariable(new HeuristicLab.Core.Variable(WEIGHT, weight));
 
-      ConstrainedIntData variable = new ConstrainedIntData();
+      StringData variable = new StringData();
       AddVariable(new HeuristicLab.Core.Variable(INDEX, variable));
-      minIndex = 0; maxIndex = 1000;
 
       ConstrainedIntData sampleOffset = new ConstrainedIntData();
@@ -84,9 +81,8 @@
       CombinedOperator combinedOp = new CombinedOperator();
       SequentialProcessor seq = new SequentialProcessor();
-      UniformRandomizer indexRandomizer = new UniformRandomizer();
-      indexRandomizer.Min = minIndex;
-      indexRandomizer.Max = maxIndex + 1; // uniform randomizer generates numbers in the range [min, max[
-      indexRandomizer.GetVariableInfo("Value").ActualName = INDEX;
-      indexRandomizer.Name = "Index Randomizer";
+      UniformItemChooser variableRandomizer = new UniformItemChooser();
+      variableRandomizer.GetVariableInfo("Value").ActualName = INDEX;
+      variableRandomizer.GetVariableInfo("Values").ActualName = "InputVariables";
+      variableRandomizer.Name = "Variable randomizer";
       NormalRandomizer weightRandomizer = new NormalRandomizer();
       weightRandomizer.Mu = 0.0;
@@ -101,9 +97,9 @@
 
       combinedOp.OperatorGraph.AddOperator(seq);
-      combinedOp.OperatorGraph.AddOperator(indexRandomizer);
+      combinedOp.OperatorGraph.AddOperator(variableRandomizer);
       combinedOp.OperatorGraph.AddOperator(weightRandomizer);
       combinedOp.OperatorGraph.AddOperator(offsetRandomizer);
       combinedOp.OperatorGraph.InitialOperator = seq;
-      seq.AddSubOperator(indexRandomizer);
+      seq.AddSubOperator(variableRandomizer);
       seq.AddSubOperator(weightRandomizer);
       seq.AddSubOperator(offsetRandomizer);
@@ -120,9 +116,8 @@
       CombinedOperator combinedOp = new CombinedOperator();
       SequentialProcessor seq = new SequentialProcessor();
-      UniformRandomizer indexRandomizer = new UniformRandomizer();
-      indexRandomizer.Min = minIndex;
-      indexRandomizer.Max = maxIndex + 1;
-      indexRandomizer.GetVariableInfo("Value").ActualName = INDEX;
-      indexRandomizer.Name = "Index Randomizer";
+      UniformItemChooser variableRandomizer = new UniformItemChooser();
+      variableRandomizer.GetVariableInfo("Value").ActualName = INDEX;
+      variableRandomizer.GetVariableInfo("Values").ActualName = "InputVariables";
+      variableRandomizer.Name = "Variable randomizer";
       NormalRandomAdder weightRandomAdder = new NormalRandomAdder();
       weightRandomAdder.Mu = 0.0;
@@ -137,9 +132,9 @@
 
       combinedOp.OperatorGraph.AddOperator(seq);
-      combinedOp.OperatorGraph.AddOperator(indexRandomizer);
+      combinedOp.OperatorGraph.AddOperator(variableRandomizer);
       combinedOp.OperatorGraph.AddOperator(weightRandomAdder);
       combinedOp.OperatorGraph.AddOperator(offsetRandomAdder);
       combinedOp.OperatorGraph.InitialOperator = seq;
-      seq.AddSubOperator(indexRandomizer);
+      seq.AddSubOperator(variableRandomizer);
       seq.AddSubOperator(weightRandomAdder);
       seq.AddSubOperator(offsetRandomAdder);
@@ -152,5 +147,5 @@
     }
 
-    public void SetConstraints(int minInputIndex, int maxInputIndex, int minSampleOffset, int maxSampleOffset) {
+    public void SetConstraints(int minSampleOffset, int maxSampleOffset) {
       ConstrainedIntData offset = GetVariableValue<ConstrainedIntData>(OFFSET, null, false);
       IntBoundedConstraint offsetConstraint = new IntBoundedConstraint();
@@ -165,15 +160,15 @@
       offset.AddConstraint(offsetConstraint);
 
-      ConstrainedIntData index = GetVariableValue<ConstrainedIntData>(INDEX, null, false);
-      IntBoundedConstraint indexConstraint = new IntBoundedConstraint();
-      minIndex = minInputIndex;
-      maxIndex = maxInputIndex;
-      indexConstraint.LowerBound = minInputIndex;
-      indexConstraint.LowerBoundEnabled = true;
-      indexConstraint.LowerBoundIncluded = true;
-      indexConstraint.UpperBound = maxInputIndex;
-      indexConstraint.UpperBoundEnabled = true;
-      indexConstraint.UpperBoundIncluded = true;
-      index.AddConstraint(indexConstraint);
+      //ConstrainedIntData index = GetVariableValue<ConstrainedIntData>(INDEX, null, false);
+      //IntBoundedConstraint indexConstraint = new IntBoundedConstraint();
+      //minIndex = minInputIndex;
+      //maxIndex = maxInputIndex;
+      //indexConstraint.LowerBound = minInputIndex;
+      //indexConstraint.LowerBoundEnabled = true;
+      //indexConstraint.LowerBoundIncluded = true;
+      //indexConstraint.UpperBound = maxInputIndex;
+      //indexConstraint.UpperBoundEnabled = true;
+      //indexConstraint.UpperBoundIncluded = true;
+      //index.AddConstraint(indexConstraint);
 
       SetupInitialization();
Index: trunk/sources/HeuristicLab.GP/3.3/BakedFunctionTree.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/3.3/BakedFunctionTree.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.GP/3.3/BakedFunctionTree.cs	(revision 2174)
@@ -34,5 +34,5 @@
     public byte arity = 0;
     public IFunction functionType;
-    public List<double> data = new List<double>();
+    public List<object> localData = new List<object>();
 
     public LightWeightFunction Clone() {
@@ -40,5 +40,5 @@
       clone.arity = arity;
       clone.functionType = functionType;
-      clone.data.AddRange(data);
+      clone.localData.AddRange(localData);
       return clone;
     }
@@ -50,5 +50,5 @@
       get {
         FlattenVariables();
-        FlattenTrees(); 
+        FlattenTrees();
         return linearRepresentation;
       }
@@ -72,6 +72,6 @@
       variables = new List<IVariable>();
       variablesExpanded = true;
-      foreach(IVariableInfo variableInfo in function.VariableInfos) {
-        if(variableInfo.Local) {
+      foreach (IVariableInfo variableInfo in function.VariableInfos) {
+        if (variableInfo.Local) {
           variables.Add((IVariable)function.GetVariable(variableInfo.FormalName).Clone());
         }
@@ -84,23 +84,11 @@
       fun.functionType = tree.Function;
       linearRepresentation.Add(fun);
-      foreach(IVariable variable in tree.LocalVariables) {
-        IItem value = variable.Value;
-        fun.data.Add(GetDoubleValue(value));
-      }
-      foreach(IFunctionTree subTree in tree.SubTrees) {
+      foreach (IVariable variable in tree.LocalVariables) {
+        IObjectData value = (IObjectData)variable.Value;
+        fun.localData.Add(value.Data);
+      }
+      foreach (IFunctionTree subTree in tree.SubTrees) {
         AddSubTree(new BakedFunctionTree(subTree));
       }
-    }
-
-    private double GetDoubleValue(IItem value) {
-      if(value is DoubleData) {
-        return ((DoubleData)value).Data;
-      } else if(value is ConstrainedDoubleData) {
-        return ((ConstrainedDoubleData)value).Data;
-      } else if(value is IntData) {
-        return ((IntData)value).Data;
-      } else if(value is ConstrainedIntData) {
-        return ((ConstrainedIntData)value).Data;
-      } else throw new NotSupportedException("Invalid datatype of local variable for GP");
     }
 
@@ -108,5 +96,5 @@
       int arity = linearRepresentation[branchRoot].arity;
       int length = 1;
-      for(int i = 0; i < arity; i++) {
+      for (int i = 0; i < arity; i++) {
         length += BranchLength(branchRoot + length);
       }
@@ -115,7 +103,7 @@
 
     private void FlattenTrees() {
-      if(treesExpanded) {
+      if (treesExpanded) {
         linearRepresentation[0].arity = (byte)subTrees.Count;
-        foreach(BakedFunctionTree subTree in subTrees) {
+        foreach (BakedFunctionTree subTree in subTrees) {
           subTree.FlattenVariables();
           subTree.FlattenTrees();
@@ -128,8 +116,10 @@
 
     private void FlattenVariables() {
-      if(variablesExpanded) {
-        linearRepresentation[0].data.Clear();
-        foreach(IVariable variable in variables) {
-          linearRepresentation[0].data.Add(GetDoubleValue(variable.Value));
+      if (variablesExpanded) {
+        linearRepresentation[0].localData.Clear();
+        foreach (IVariable variable in variables) {
+          object objData = variable.Value;
+          while (objData is IObjectData) objData = ((IObjectData)objData).Data;
+          linearRepresentation[0].localData.Add(objData);
         }
         variablesExpanded = false;
@@ -140,12 +130,12 @@
     public int Size {
       get {
-        if(treesExpanded) {
+        if (treesExpanded) {
           int size = 1;
-          foreach(BakedFunctionTree tree in subTrees) {
+          foreach (BakedFunctionTree tree in subTrees) {
             size += tree.Size;
           }
           return size;
-        } else 
-        return linearRepresentation.Count;
+        } else
+          return linearRepresentation.Count;
       }
     }
@@ -153,11 +143,11 @@
     public int Height {
       get {
-        if(treesExpanded) {
+        if (treesExpanded) {
           int height = 0;
-          foreach(IFunctionTree subTree in subTrees) {
+          foreach (IFunctionTree subTree in subTrees) {
             int curHeight = subTree.Height;
-            if(curHeight > height) height = curHeight;
-          }
-          return height+1;
+            if (curHeight > height) height = curHeight;
+          }
+          return height + 1;
         } else {
           int nextBranchStart;
@@ -171,7 +161,7 @@
       int height = 0;
       branchStart++;
-      for(int i = 0; i < f.arity; i++) {
+      for (int i = 0; i < f.arity; i++) {
         int curHeight = BranchHeight(branchStart, out nextBranchStart);
-        if(curHeight > height) height = curHeight;
+        if (curHeight > height) height = curHeight;
         branchStart = nextBranchStart;
       }
@@ -182,12 +172,12 @@
     public IList<IFunctionTree> SubTrees {
       get {
-        if(!treesExpanded) {
+        if (!treesExpanded) {
           subTrees = new List<IFunctionTree>();
           int arity = linearRepresentation[0].arity;
           int branchIndex = 1;
-          for(int i = 0; i < arity; i++) {
+          for (int i = 0; i < arity; i++) {
             BakedFunctionTree subTree = new BakedFunctionTree();
             int length = BranchLength(branchIndex);
-            for(int j = branchIndex; j < branchIndex + length; j++) {
+            for (int j = branchIndex; j < branchIndex + length; j++) {
               subTree.linearRepresentation.Add(linearRepresentation[j]);
             }
@@ -205,21 +195,19 @@
     public ICollection<IVariable> LocalVariables {
       get {
-        if(!variablesExpanded) {
+        if (!variablesExpanded) {
           variables = new List<IVariable>();
           IFunction function = Function;
           int localVariableIndex = 0;
-          foreach(IVariableInfo variableInfo in function.VariableInfos) {
-            if(variableInfo.Local) {
+          foreach (IVariableInfo variableInfo in function.VariableInfos) {
+            if (variableInfo.Local) {
               IVariable clone = (IVariable)function.GetVariable(variableInfo.FormalName).Clone();
-              IItem value = clone.Value;
-              if(value is ConstrainedDoubleData) {
-                ((ConstrainedDoubleData)value).Data = linearRepresentation[0].data[localVariableIndex];
-              } else if(value is ConstrainedIntData) {
-                ((ConstrainedIntData)value).Data = (int)linearRepresentation[0].data[localVariableIndex];
-              } else if(value is DoubleData) {
-                ((DoubleData)value).Data = linearRepresentation[0].data[localVariableIndex];
-              } else if(value is IntData) {
-                ((IntData)value).Data = (int)linearRepresentation[0].data[localVariableIndex];
-              } else throw new NotSupportedException("Invalid local variable type for GP.");
+              IObjectData objData = (IObjectData)clone.Value;
+              if (objData is ConstrainedDoubleData) {
+                ((ConstrainedDoubleData)objData).Data = (double)linearRepresentation[0].localData[localVariableIndex];
+              } else if (objData is ConstrainedIntData) {
+                ((ConstrainedIntData)objData).Data = (int)linearRepresentation[0].localData[localVariableIndex];
+              } else {
+                objData.Data = linearRepresentation[0].localData[localVariableIndex];
+              }
               variables.Add(clone);
               localVariableIndex++;
@@ -227,5 +215,5 @@
           }
           variablesExpanded = true;
-          linearRepresentation[0].data.Clear();
+          linearRepresentation[0].localData.Clear();
         }
         return variables;
@@ -238,6 +226,6 @@
 
     public IVariable GetLocalVariable(string name) {
-      foreach(IVariable var in LocalVariables) {
-        if(var.Name == name) return var;
+      foreach (IVariable var in LocalVariables) {
+        if (var.Name == name) return var;
       }
       return null;
@@ -253,10 +241,10 @@
 
     public void AddSubTree(IFunctionTree tree) {
-      if(!treesExpanded) throw new InvalidOperationException();
+      if (!treesExpanded) throw new InvalidOperationException();
       subTrees.Add(tree);
     }
 
     public void InsertSubTree(int index, IFunctionTree tree) {
-      if(!treesExpanded) throw new InvalidOperationException();
+      if (!treesExpanded) throw new InvalidOperationException();
       subTrees.Insert(index, tree);
     }
@@ -264,5 +252,5 @@
     public void RemoveSubTree(int index) {
       // sanity check
-      if(!treesExpanded) throw new InvalidOperationException();
+      if (!treesExpanded) throw new InvalidOperationException();
       subTrees.RemoveAt(index);
     }
@@ -273,13 +261,13 @@
       XmlNode node = base.GetXmlNode(name, document, persistedObjects);
       XmlNode linearRepresentationNode = document.CreateElement("LinearRepresentation");
-      foreach(LightWeightFunction f in linearRepresentation) {
-        XmlNode entryNode = PersistenceManager.Persist("FunctionType", f.functionType, document, persistedObjects);
+      foreach (LightWeightFunction f in linearRepresentation) {
+        XmlNode entryNode = PersistenceManager.Persist("Function", f.functionType, document, persistedObjects);
         XmlAttribute arityAttribute = document.CreateAttribute("Arity");
-        arityAttribute.Value = f.arity+"";
+        arityAttribute.Value = XmlConvert.ToString(f.arity);
         entryNode.Attributes.Append(arityAttribute);
-        if(f.data.Count > 0) {
-          XmlAttribute dataAttribute = document.CreateAttribute("Data");
-          dataAttribute.Value = GetString(f.data);
-          entryNode.Attributes.Append(dataAttribute);
+        foreach (object o in f.localData) {
+          if (f.localData.Count > 0) {
+            entryNode.AppendChild(CreateDataNode(document, o));
+          }
         }
         linearRepresentationNode.AppendChild(entryNode);
@@ -287,4 +275,21 @@
 
       node.AppendChild(linearRepresentationNode);
+      return node;
+    }
+
+    private XmlNode CreateDataNode(XmlDocument doc, object o) {
+      XmlNode node = doc.CreateElement("Data");
+      XmlAttribute typeAttr = doc.CreateAttribute("Type");
+      node.Attributes.Append(typeAttr);
+      if (o is double) {
+        node.Value = XmlConvert.ToString((double)o);
+        typeAttr.Value = "d";
+      } else if (o is int) {
+        node.Value = XmlConvert.ToString((int)o);
+        typeAttr.Value = "i";
+      } else if (o is string) {
+        node.Value = (string)o;
+        typeAttr.Value = "s";
+      } else throw new ArgumentException("Invalid type for local data element: " + o);
       return node;
     }
@@ -293,9 +298,10 @@
       base.Populate(node, restoredObjects);
       XmlNode linearRepresentationNode = node.SelectSingleNode("LinearRepresentation");
-      foreach(XmlNode entryNode in linearRepresentationNode.ChildNodes) {
+      foreach (XmlNode entryNode in linearRepresentationNode.ChildNodes) {
         LightWeightFunction f = new LightWeightFunction();
-        f.arity = byte.Parse(entryNode.Attributes["Arity"].Value, CultureInfo.InvariantCulture);
-        if(entryNode.Attributes["Data"]!=null) 
-          f.data = GetList<double>(entryNode.Attributes["Data"].Value, s => double.Parse(s, CultureInfo.InvariantCulture));
+        f.arity = XmlConvert.ToByte(entryNode.Attributes["Arity"].Value);
+        foreach (XmlNode dataNode in entryNode.ChildNodes) {
+          f.localData.Add(ParseDataNode(dataNode));
+        }
         f.functionType = (IFunction)PersistenceManager.Restore(entryNode, restoredObjects);
         linearRepresentation.Add(f);
@@ -305,29 +311,40 @@
     }
 
-    private string GetString(IEnumerable<double> xs) {
-      StringBuilder builder = new StringBuilder();
-      foreach(double x in xs) {
-        builder.Append(x.ToString("r", CultureInfo.InvariantCulture) + "; ");
-      }
-      if(builder.Length > 0) builder.Remove(builder.Length - 2, 2);
-      return builder.ToString();
-    }
-
-    private List<T> GetList<T>(string s, Converter<string, T> converter) {
-      List<T> result = new List<T>();
-      string[] tokens = s.Split(new char[] { ';', ' ' }, StringSplitOptions.RemoveEmptyEntries);
-      foreach(string token in tokens) {
-        T x = converter(token.Trim());
-        result.Add(x);
-      }
-      return result;
-    }
+    private object ParseDataNode(XmlNode dataNode) {
+      string type = dataNode.Attributes["Type"].Value;
+      if (type == "d") {
+        return XmlConvert.ToDouble(dataNode.Value);
+      } else if (type == "i") {
+        return XmlConvert.ToInt32(dataNode.Value);
+      } else if (type == "s") {
+        return dataNode.Value;
+      } else throw new FormatException("Can't parse type \"" + type + "\" \"" + dataNode.Value + "\" as local data for GP trees");
+    }
+
+    //private string GetString(IEnumerable<double> xs) {
+    //  StringBuilder builder = new StringBuilder();
+    //  foreach (double x in xs) {
+    //    builder.Append(x.ToString("r", CultureInfo.InvariantCulture) + "; ");
+    //  }
+    //  if (builder.Length > 0) builder.Remove(builder.Length - 2, 2);
+    //  return builder.ToString();
+    //}
+
+    //private List<T> GetList<T>(string s, Converter<string, T> converter) {
+    //  List<T> result = new List<T>();
+    //  string[] tokens = s.Split(new char[] { ';', ' ' }, StringSplitOptions.RemoveEmptyEntries);
+    //  foreach (string token in tokens) {
+    //    T x = converter(token.Trim());
+    //    result.Add(x);
+    //  }
+    //  return result;
+    //}
 
     public override object Clone(IDictionary<Guid, object> clonedObjects) {
       BakedFunctionTree clone = new BakedFunctionTree();
       // in case the user (de)serialized the tree between evaluation and selection we have to flatten the tree again.
-      if(treesExpanded) FlattenTrees();
-      if(variablesExpanded) FlattenVariables();
-      foreach(LightWeightFunction f in linearRepresentation) {
+      if (treesExpanded) FlattenTrees();
+      if (variablesExpanded) FlattenVariables();
+      foreach (LightWeightFunction f in linearRepresentation) {
         clone.linearRepresentation.Add(f.Clone());
       }
Index: trunk/sources/HeuristicLab.Modeling/3.2/ProblemInjector.cs
===================================================================
--- trunk/sources/HeuristicLab.Modeling/3.2/ProblemInjector.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.Modeling/3.2/ProblemInjector.cs	(revision 2174)
@@ -78,4 +78,5 @@
       AddVariableInfo(new VariableInfo("MaxNumberOfTrainingSamples", "Maximal number of training samples to use (optional)", typeof(IntData), VariableKind.In));
       AddVariableInfo(new VariableInfo("NumberOfInputVariables", "The number of available input variables", typeof(IntData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("InputVariables", "List of input variable names", typeof(ItemList), VariableKind.New));
     }
 
@@ -97,8 +98,13 @@
 
       Dataset scopeDataset = CreateNewDataset(operatorDataset, targetVariable, operatorAllowedFeatures);
+      ItemList inputVariables = new ItemList();
+      for (int i = 1; i < scopeDataset.Columns; i++) {
+        inputVariables.Add(new StringData(scopeDataset.GetVariableName(i)));
+      }
 
-      scope.AddVariable(new Variable("Dataset", scopeDataset));
-      scope.AddVariable(new Variable("TargetVariable", new IntData(0)));
-      scope.AddVariable(new Variable("NumberOfInputVariables", new IntData(scopeDataset.Columns - 1)));
+      scope.AddVariable(new Variable(scope.TranslateName("Dataset"), scopeDataset));
+      scope.AddVariable(new Variable(scope.TranslateName("TargetVariable"), new IntData(0)));
+      scope.AddVariable(new Variable(scope.TranslateName("NumberOfInputVariables"), new IntData(scopeDataset.Columns - 1)));
+      scope.AddVariable(new Variable(scope.TranslateName("InputVariables"), inputVariables));
 
       int trainingStart = GetVariableValue<IntData>("TrainingSamplesStart", scope, true).Data;
@@ -116,4 +122,6 @@
       scope.AddVariable(new Variable(scope.TranslateName("ActualTrainingSamplesStart"), new IntData(trainingStart)));
       scope.AddVariable(new Variable(scope.TranslateName("ActualTrainingSamplesEnd"), new IntData(trainingStart + nTrainingSamples)));
+
+
       return null;
     }
@@ -154,5 +162,5 @@
 
     private void AddVariableToScope(string variableName, IScope scope) {
-      scope.AddVariable(new Variable(variableName, (IItem)GetVariable(variableName).Value.Clone()));      
+      scope.AddVariable(new Variable(scope.TranslateName(variableName), (IItem)GetVariable(variableName).Value.Clone()));      
     }
   }
Index: trunk/sources/HeuristicLab.Random/3.2/HeuristicLab.Random-3.2.csproj
===================================================================
--- trunk/sources/HeuristicLab.Random/3.2/HeuristicLab.Random-3.2.csproj	(revision 2168)
+++ trunk/sources/HeuristicLab.Random/3.2/HeuristicLab.Random-3.2.csproj	(revision 2174)
@@ -81,4 +81,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="UniformItemChooser.cs" />
     <Compile Include="UniformRandomAdder.cs" />
     <Compile Include="NormalRandomAdder.cs" />
Index: trunk/sources/HeuristicLab.Random/3.2/UniformItemChooser.cs
===================================================================
--- trunk/sources/HeuristicLab.Random/3.2/UniformItemChooser.cs	(revision 2174)
+++ trunk/sources/HeuristicLab.Random/3.2/UniformItemChooser.cs	(revision 2174)
@@ -0,0 +1,63 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+
+namespace HeuristicLab.Random {
+  /// <summary>
+  /// UniformItemChooser takes a list of items selects one of the elements randomly and sets the selected element as value of output variable.
+  /// </summary>
+  public class UniformItemChooser : OperatorBase {
+    /// <inheritdoc select="summary"/>
+    public override string Description {
+      get { return "Initializes the value of variable 'Value' to a random value chosen uniformly from the a list of values"; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="UniformItemChooser"/> with four variable infos 
+    /// (<c>Value</c>, <c>Random</c>, <c>Max</c> and <c>Min</c>), being a random number generator 
+    /// between 0.0 and 1.0.
+    /// </summary>
+    public UniformItemChooser() {
+      AddVariableInfo(new VariableInfo("Value", "The value to manipulate", typeof(IItem), VariableKind.Out));
+      AddVariableInfo(new VariableInfo("Random", "The random generator to use", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Values", "The list of possible values", typeof(ItemList), VariableKind.In));
+    }
+
+    /// <summary>
+    /// Selects a random element from 'values' and sets the selected element as value of variable 'Value'
+    /// </summary>
+    /// <param name="scope">The scope where to apply the random number generator.</param>
+    /// <returns><c>null</c>.</returns>
+    public override IOperation Apply(IScope scope) {
+      IVariable value = scope.GetVariable(scope.TranslateName("Value"));
+      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
+      ItemList values = GetVariableValue<ItemList>("Values", scope, true);
+      value.Value = values[mt.Next(values.Count)];
+      return null;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Random/3.2/UniformRandomizer.cs
===================================================================
--- trunk/sources/HeuristicLab.Random/3.2/UniformRandomizer.cs	(revision 2168)
+++ trunk/sources/HeuristicLab.Random/3.2/UniformRandomizer.cs	(revision 2174)
@@ -63,5 +63,5 @@
     /// </summary>
     public UniformRandomizer() {
-      AddVariableInfo(new VariableInfo("Value", "The value to manipulate (type is one of: IntData, ConstrainedIntData, DoubleData, ConstrainedDoubleData)", typeof(IObjectData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Value", "The value to manipulate (type is one of: IntData, ConstrainedIntData, DoubleData, ConstrainedDoubleData)", typeof(IObjectData), VariableKind.Out));
       AddVariableInfo(new VariableInfo("Random", "The random generator to use", typeof(MersenneTwister), VariableKind.In));
       AddVariableInfo(new VariableInfo("Min", "Lower bound of the uniform distribution (inclusive)", typeof(DoubleData), VariableKind.None));
