Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/SolutionComparisonView.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/SolutionComparisonView.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/SolutionComparisonView.cs	(revision 14249)
@@ -66,5 +66,5 @@
       var usedFactorVariables =
         symbolicSolution.Model.SymbolicExpressionTree.IterateNodesPostfix()
-        .OfType<FactorVariableTreeNode>()
+        .OfType<BinaryFactorVariableTreeNode>()
         .Select(node => Tuple.Create(node.VariableName, node.VariableValue))
         .Distinct();
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs	(revision 14249)
@@ -60,5 +60,5 @@
       var usedFactorVariables =
         Content.Model.SymbolicExpressionTree.IterateNodesPostfix()
-        .OfType<FactorVariableTreeNode>()
+        .OfType<BinaryFactorVariableTreeNode>()
         .Select(node => Tuple.Create(node.VariableName, node.VariableValue))
         .Distinct();
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 14249)
@@ -205,11 +205,15 @@
           ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
           VariableTreeNode variableTreeNode = node as VariableTreeNode;
-          BinaryFactorVariableTreeNode factorVariableTreeNode = node as BinaryFactorVariableTreeNode;
+          BinaryFactorVariableTreeNode binFactorVarTreeNode = node as BinaryFactorVariableTreeNode;
+          FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
           if (constantTreeNode != null)
             c[i++] = constantTreeNode.Value;
           else if (updateVariableWeights && variableTreeNode != null)
             c[i++] = variableTreeNode.Weight;
-          else if (updateVariableWeights && factorVariableTreeNode != null)
-            c[i++] = factorVariableTreeNode.Weight;
+          else if (updateVariableWeights && binFactorVarTreeNode != null)
+            c[i++] = binFactorVarTreeNode.Weight;
+          else if (factorVarTreeNode != null) {
+            foreach (var w in factorVarTreeNode.Weights) c[i++] = w;
+          }
         }
       }
@@ -248,9 +252,7 @@
         alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, null, null);
         alglib.lsfitresults(state, out info, out c, out rep);
-      }
-      catch (ArithmeticException) {
+      } catch (ArithmeticException) {
         return originalQuality;
-      }
-      catch (alglib.alglibexception) {
+      } catch (alglib.alglibexception) {
         return originalQuality;
       }
@@ -273,11 +275,15 @@
         ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
         VariableTreeNode variableTreeNode = node as VariableTreeNode;
-        BinaryFactorVariableTreeNode factorVarTreeNode = node as BinaryFactorVariableTreeNode;
+        BinaryFactorVariableTreeNode binFactorVarTreeNode = node as BinaryFactorVariableTreeNode;
+        FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
         if (constantTreeNode != null)
           constantTreeNode.Value = constants[i++];
         else if (updateVariableWeights && variableTreeNode != null)
           variableTreeNode.Weight = constants[i++];
-        else if (updateVariableWeights && factorVarTreeNode != null)
-          factorVarTreeNode.Weight = constants[i++];
+        else if (updateVariableWeights && binFactorVarTreeNode != null)
+          binFactorVarTreeNode.Weight = constants[i++];
+        else if (factorVarTreeNode != null) {
+          foreach (var w in factorVarTreeNode.Weights) constants[i++] = w;
+        }
       }
     }
@@ -321,4 +327,21 @@
           term = par;
         }
+        return true;
+      }
+      if (node.Symbol is FactorVariable) {
+        var factorVarNode = node as FactorVariableTreeNode;
+        var products = new List<Term>();
+        foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) {
+          var par = new AutoDiff.Variable();
+          parameters.Add(par);
+          variableNames.Add(factorVarNode.VariableName);
+          categoricalVariableValues.Add(variableValue);
+
+          var wVar = new AutoDiff.Variable();
+          variables.Add(wVar);
+
+          products.Add(AutoDiff.TermBuilder.Product(wVar, par));
+        }
+        term = AutoDiff.TermBuilder.Sum(products);
         return true;
       }
@@ -494,4 +517,5 @@
          !(n.Symbol is Variable) &&
          !(n.Symbol is BinaryFactorVariable) &&
+         !(n.Symbol is FactorVariable) &&
          !(n.Symbol is Constant) &&
          !(n.Symbol is Addition) &&
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs	(revision 14249)
@@ -53,7 +53,8 @@
       constant.MaxValue = 20;
       var variableSymbol = new HeuristicLab.Problems.DataAnalysis.Symbolic.Variable();
-      var factorVariableSymbol = new BinaryFactorVariable();
+      var binFactorVariableSymbol = new BinaryFactorVariable();
+      var factorVariableSymbol = new FactorVariable();
 
-      var allSymbols = new List<Symbol>() { add, sub, mul, div, constant, variableSymbol, factorVariableSymbol };
+      var allSymbols = new List<Symbol>() { add, sub, mul, div, constant, variableSymbol, binFactorVariableSymbol, factorVariableSymbol};
       var functionSymbols = new List<Symbol>() { add, sub, mul, div };
 
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 14249)
@@ -115,5 +115,6 @@
       constant.MaxValue = 20;
       var variableSymbol = new HeuristicLab.Problems.DataAnalysis.Symbolic.Variable();
-      var factorVariable = new BinaryFactorVariable();
+      var binFactorVariable = new BinaryFactorVariable();
+      var factorVariable = new FactorVariable();
       var laggedVariable = new LaggedVariable();
       laggedVariable.InitialFrequency = 0.0;
@@ -124,5 +125,5 @@
       var allSymbols = new List<Symbol>() { add, sub, mul, div, mean, sin, cos, tan, log, square, pow, sqrt, root, exp,
         airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, fresnelCosineIntegral, fresnelSineIntegral, gamma, hypCosineIntegral, hypSineIntegral, norm, psi, sineIntegral,
-        @if, gt, lt, and, or, not,xor, timeLag, integral, derivative, constant, variableSymbol, factorVariable, laggedVariable,autoregressiveVariable, variableCondition };
+        @if, gt, lt, and, or, not,xor, timeLag, integral, derivative, constant, variableSymbol, binFactorVariable, factorVariable, laggedVariable,autoregressiveVariable, variableCondition };
       var unaryFunctionSymbols = new List<Symbol>() { square, sqrt, sin, cos, tan, log, exp, not, timeLag, integral, derivative,
         airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, fresnelCosineIntegral, fresnelSineIntegral, gamma, hypCosineIntegral, hypSineIntegral, norm, psi, sineIntegral
@@ -131,5 +132,5 @@
       var binaryFunctionSymbols = new List<Symbol>() { pow, root, gt, lt, variableCondition };
       var ternarySymbols = new List<Symbol>() { add, sub, mul, div, mean, and, or, xor };
-      var terminalSymbols = new List<Symbol>() { variableSymbol, factorVariable, constant, laggedVariable, autoregressiveVariable };
+      var terminalSymbols = new List<Symbol>() { variableSymbol, binFactorVariable, factorVariable, constant, laggedVariable, autoregressiveVariable };
 
       foreach (var symb in allSymbols)
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 14249)
@@ -104,5 +104,6 @@
       constant.MaxValue = 20;
       var variableSymbol = new Variable();
-      var factorVariable = new BinaryFactorVariable();
+      var binFactorVariable = new BinaryFactorVariable();
+      var factorVariable = new FactorVariable();
       var laggedVariable = new LaggedVariable();
       var autoregressiveVariable = new AutoregressiveTargetVariable();
@@ -115,5 +116,5 @@
       var specialFunctions = new GroupSymbol(SpecialFunctionsName, new List<ISymbol> { airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, 
         fresnelCosineIntegral,fresnelSineIntegral,gamma,hypCosineIntegral,hypSineIntegral,norm, psi, sineIntegral});
-      var terminalSymbols = new GroupSymbol(TerminalsName, new List<ISymbol> { constant, variableSymbol, factorVariable });
+      var terminalSymbols = new GroupSymbol(TerminalsName, new List<ISymbol> { constant, variableSymbol, binFactorVariable, factorVariable });
       var realValuedSymbols = new GroupSymbol(RealValuedSymbolsName, new List<ISymbol>() { arithmeticSymbols, trigonometricSymbols, exponentialAndLogarithmicSymbols, specialFunctions, terminalSymbols });
 
@@ -123,5 +124,5 @@
       var comparisonSymbols = new GroupSymbol(ComparisonsName, new List<ISymbol> { gt, lt });
       var booleanOperationSymbols = new GroupSymbol(BooleanOperatorsName, new List<ISymbol> { and, or, not, xor });
-      var conditionalSymbols = new GroupSymbol(ConditionalSymbolsName, new List<ISymbol> { conditionSymbols, comparisonSymbols, booleanOperationSymbols }); // TODO: factorVariableBool?
+      var conditionalSymbols = new GroupSymbol(ConditionalSymbolsName, new List<ISymbol> { conditionSymbols, comparisonSymbols, booleanOperationSymbols }); 
 
       var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List<ISymbol> { timeLag, integral, derivative, laggedVariable, autoregressiveVariable });
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 14249)
@@ -199,6 +199,8 @@
     <Compile Include="Symbols\AiryB.cs" />
     <Compile Include="Symbols\Bessel.cs" />
+    <Compile Include="Symbols\BinaryFactorVariable.cs" />
+    <Compile Include="Symbols\BinaryFactorVariableTreeNode.cs" />
+    <Compile Include="Symbols\FactorVariableTreeNode.cs" />
     <Compile Include="Symbols\FactorVariable.cs" />
-    <Compile Include="Symbols\FactorVariableTreeNode.cs" />
     <Compile Include="Symbols\VariableBase.cs" />
     <Compile Include="Symbols\VariableTreeNodeBase.cs" />
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs	(revision 14249)
@@ -84,4 +84,6 @@
     public const byte Bessel = 44;
     public const byte FactorVariable = 46;
+    public const byte BinaryFactorVariable = 47;
+
 
     private static Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
@@ -132,5 +134,6 @@
       { typeof(Erf), OpCodes.Erf},
       { typeof(Bessel), OpCodes.Bessel},
-      { typeof(BinaryFactorVariable), OpCodes.FactorVariable }
+      { typeof(FactorVariable), OpCodes.FactorVariable },
+      { typeof(BinaryFactorVariable), OpCodes.BinaryFactorVariable }
     };
 
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 14249)
@@ -66,5 +66,5 @@
     private static MethodInfo erf = thisType.GetMethod("Erf", new Type[] { typeof(double) });
     private static MethodInfo bessel = thisType.GetMethod("Bessel", new Type[] { typeof(double) });
-    private static MethodInfo string_eq = typeof(string).GetMethod("Equals", new Type[] {typeof(string)});
+    private static MethodInfo string_eq = typeof(string).GetMethod("Equals", new Type[] { typeof(string) });
     #endregion
 
@@ -628,39 +628,7 @@
             return;
           }
-        case OpCodes.FactorVariable: {
-            BinaryFactorVariableTreeNode varNode = currentInstr.dynamicNode as BinaryFactorVariableTreeNode;
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.data);
-            // load correct column of the current variable
-            il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
-            if (!state.InLaggedContext) {
-              il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.VariableValue); 
-              il.Emit(System.Reflection.Emit.OpCodes.Call, string_eq);
-              throw new NotSupportedException();
-              // TODO: convert bool to 1 / 0?
-            } else {
-              var nanResult = il.DefineLabel();
-              var normalResult = il.DefineLabel();
-              il.Emit(System.Reflection.Emit.OpCodes.Dup);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
-              il.Emit(System.Reflection.Emit.OpCodes.Blt, nanResult);
-              il.Emit(System.Reflection.Emit.OpCodes.Dup);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
-              il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
-              il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.VariableValue);
-              il.Emit(System.Reflection.Emit.OpCodes.Call, string_eq);
-              throw new NotSupportedException();
-              // TODO: convert bool to 1 / 0?
-              il.Emit(System.Reflection.Emit.OpCodes.Br, normalResult);
-              il.MarkLabel(nanResult);
-              il.Emit(System.Reflection.Emit.OpCodes.Pop); // rowIndex
-              il.Emit(System.Reflection.Emit.OpCodes.Pop); // column reference
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, double.NaN);
-              il.MarkLabel(normalResult);
-            }
-            return;
+        case OpCodes.FactorVariable:
+        case OpCodes.BinaryFactorVariable: {
+            throw new NotSupportedException();
           }
         case OpCodes.LagVariable: {
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 14249)
@@ -146,5 +146,5 @@
         } else if (instr.opCode == OpCodes.FactorVariable) {
           var factorTreeNode = instr.dynamicNode as BinaryFactorVariableTreeNode;
-          instr.data = dataset.GetReadOnlyStringValues(factorTreeNode.VariableName); 
+          instr.data = dataset.GetReadOnlyStringValues(factorTreeNode.VariableName);
         } else if (instr.opCode == OpCodes.LagVariable) {
           var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
@@ -459,8 +459,13 @@
             return ((IList<double>)currentInstr.data)[row] * variableTreeNode.Weight;
           }
-        case OpCodes.FactorVariable: {
+        case OpCodes.BinaryFactorVariable: {
             if (row < 0 || row >= dataset.Rows) return double.NaN;
             var factorVarTreeNode = currentInstr.dynamicNode as BinaryFactorVariableTreeNode;
             return ((IList<string>)currentInstr.data)[row] == factorVarTreeNode.VariableValue ? factorVarTreeNode.Weight : 0;
+          }
+        case OpCodes.FactorVariable: {
+            if (row < 0 || row >= dataset.Rows) return double.NaN;
+            var factorVarTreeNode = currentInstr.dynamicNode as FactorVariableTreeNode;
+            return factorVarTreeNode.GetValue(((IList<string>)currentInstr.data)[row]);
           }
         case OpCodes.LagVariable: {
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 14249)
@@ -148,9 +148,15 @@
             instr.value = ((IList<double>)instr.data)[row] * variableTreeNode.Weight;
           }
+        } else if (instr.opCode == OpCodes.BinaryFactorVariable) {
+          if (row < 0 || row >= dataset.Rows) instr.value = double.NaN;
+          else {
+            var factorTreeNode = instr.dynamicNode as BinaryFactorVariableTreeNode;
+            instr.value = ((IList<string>)instr.data)[row] == factorTreeNode.VariableValue ? factorTreeNode.Weight : 0;
+          }
         } else if (instr.opCode == OpCodes.FactorVariable) {
           if (row < 0 || row >= dataset.Rows) instr.value = double.NaN;
           else {
-            var factorTreeNode = instr.dynamicNode as BinaryFactorVariableTreeNode;
-            instr.value = ((IList<string>)instr.data)[row] == factorTreeNode.VariableValue ? factorTreeNode.Weight : 0;
+            var factorTreeNode = instr.dynamicNode as FactorVariableTreeNode;
+            instr.value = factorTreeNode.GetValue(((IList<string>)instr.data)[row]);
           }
         } else if (instr.opCode == OpCodes.LagVariable) {
@@ -398,6 +404,11 @@
             }
             break;
+          case OpCodes.BinaryFactorVariable: {
+              var factorVariableTreeNode = instr.dynamicNode as BinaryFactorVariableTreeNode;
+              instr.data = dataset.GetReadOnlyStringValues(factorVariableTreeNode.VariableName);
+            }
+            break;
           case OpCodes.FactorVariable: {
-              var factorVariableTreeNode = instr.dynamicNode as BinaryFactorVariableTreeNode;
+              var factorVariableTreeNode = instr.dynamicNode as FactorVariableTreeNode;
               instr.data = dataset.GetReadOnlyStringValues(factorVariableTreeNode.VariableName);
             }
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 14249)
@@ -183,5 +183,5 @@
     }
     private bool IsVariableBase(ISymbolicExpressionTreeNode node) {
-      return node.Symbol is VariableBase;
+      return node is VariableTreeNodeBase;
     }
     private bool IsConstant(ISymbolicExpressionTreeNode node) {
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 14249)
@@ -226,4 +226,11 @@
             .ToDictionary(varName => varName, varName => ds.GetStringValues(varName).Distinct().ToList());
         }
+      } foreach (var factorSymbol in grammar.Symbols.OfType<FactorVariable>()) {
+        if (!factorSymbol.Fixed) {
+          factorSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => ds.VariableHasType<string>(x));
+          factorSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => ds.VariableHasType<string>(x));
+          factorSymbol.VariableValues = factorSymbol.VariableNames
+            .ToDictionary(varName => varName, varName => ds.GetStringValues(varName).Distinct().ToList());
+        }
       }
     }
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSingleObjectiveProblem.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSingleObjectiveProblem.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSingleObjectiveProblem.cs	(revision 14249)
@@ -73,5 +73,5 @@
     }
 
-    public SymbolicDataAnalysisSingleObjectiveProblem(T problemData, U evaluator, V solutionCreator)
+    protected SymbolicDataAnalysisSingleObjectiveProblem(T problemData, U evaluator, V solutionCreator)
       : base(problemData, evaluator, solutionCreator) {
       Parameters.Add(new FixedValueParameter<BoolValue>(MaximizationParameterName, "Set to false if the problem should be minimized."));
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 14249)
@@ -43,11 +43,15 @@
       //optimization: constant nodes return always the same value
       ConstantTreeNode constantNode = node as ConstantTreeNode;
-      BinaryFactorVariableTreeNode factorNode = node as BinaryFactorVariableTreeNode;
+      BinaryFactorVariableTreeNode binaryFactorNode = node as BinaryFactorVariableTreeNode;
+      FactorVariableTreeNode factorNode = node as FactorVariableTreeNode;
       if (constantNode != null) {
         yield return constantNode.Value;
-      } else if (factorNode != null) {
+      } else if (binaryFactorNode != null) {
         // valid replacements are either all off or all on
         yield return 0;
         yield return 1;
+      } else if (factorNode != null) {
+        foreach (var w in factorNode.Weights) yield return w;
+        yield return 0.0;
       } else {
         var rootSymbol = new ProgramRootSymbol().CreateTreeNode();
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/BinaryFactorVariable.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/BinaryFactorVariable.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/BinaryFactorVariable.cs	(revision 14249)
@@ -32,5 +32,5 @@
   public class BinaryFactorVariable : VariableBase {
 
-    private Dictionary<string, List<string>> variableValues;
+    private readonly Dictionary<string, List<string>> variableValues;
 
     [Storable]
@@ -63,5 +63,5 @@
 
     public override ISymbolicExpressionTreeNode CreateTreeNode() {
-      return new FactorVariableTreeNode(this);
+      return new BinaryFactorVariableTreeNode(this);
     }
 
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/BinaryFactorVariableTreeNode.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/BinaryFactorVariableTreeNode.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/BinaryFactorVariableTreeNode.cs	(revision 14249)
@@ -44,5 +44,4 @@
       variableValue = original.variableValue;
     }
-    protected BinaryFactorVariableTreeNode() { }
     public BinaryFactorVariableTreeNode(BinaryFactorVariable variableSymbol) : base(variableSymbol) { }
 
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariable.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariable.cs	(revision 14249)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariable.cs	(revision 14249)
@@ -0,0 +1,74 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [StorableClass]
+  [Item("FactorVariable", "Represents a categorical variable (comparable to factors as in R).")]
+  public class FactorVariable : VariableBase {
+    private readonly Dictionary<string, List<string>> variableValues;
+    [Storable]
+    public IEnumerable<KeyValuePair<string, List<string>>> VariableValues {
+      get { return variableValues; }
+      set {
+        if (value == null) throw new ArgumentNullException();
+        variableValues.Clear();
+        foreach (var kvp in value) {
+          variableValues.Add(kvp.Key, new List<string>(kvp.Value));
+        }
+      }
+    }
+
+    [StorableConstructor]
+    protected FactorVariable(bool deserializing)
+      : base(deserializing) {
+      variableValues = new Dictionary<string, List<string>>();
+    }
+    protected FactorVariable(FactorVariable original, Cloner cloner)
+      : base(original, cloner) {
+      variableValues =
+        original.variableValues.ToDictionary(kvp => kvp.Key, kvp => new List<string>(kvp.Value));
+    }
+    public FactorVariable() : this("FactorVariable", "Represents a categorical variable (comparable to factors as in R).") { }
+    public FactorVariable(string name, string description)
+      : base(name, description) {
+      variableValues = new Dictionary<string, List<string>>();
+    }
+
+    public override ISymbolicExpressionTreeNode CreateTreeNode() {
+      return new FactorVariableTreeNode(this);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FactorVariable(this, cloner);
+    }
+
+    public IEnumerable<string> GetVariableValues(string variableName) {
+      return variableValues[variableName];
+    }
+  }
+}
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariableTreeNode.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariableTreeNode.cs	(revision 14249)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariableTreeNode.cs	(revision 14249)
@@ -0,0 +1,120 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [StorableClass]
+  public class FactorVariableTreeNode : SymbolicExpressionTreeTerminalNode, IVariableTreeNode {
+    public new FactorVariable Symbol {
+      get { return (FactorVariable)base.Symbol; }
+    }
+    [Storable]
+    private double[] weights;
+    public double[] Weights {
+      get { return weights; }
+      set { weights = value; }
+    }
+    [Storable]
+    private string variableName;
+    public string VariableName {
+      get { return variableName; }
+      set { variableName = value; }
+    }
+
+    [StorableConstructor]
+    protected FactorVariableTreeNode(bool deserializing) : base(deserializing) { }
+    protected FactorVariableTreeNode(FactorVariableTreeNode original, Cloner cloner)
+      : base(original, cloner) {
+      variableName = original.variableName;
+      if (original.weights != null) {
+        this.weights = new double[original.Weights.Length];
+        Array.Copy(original.Weights, weights, weights.Length);
+      }
+    }
+
+    public FactorVariableTreeNode(FactorVariable variableSymbol)
+      : base(variableSymbol) {
+    }
+
+    public override bool HasLocalParameters {
+      get { return true; }
+    }
+
+    public override void ResetLocalParameters(IRandom random) {
+      base.ResetLocalParameters(random);
+      variableName = Symbol.VariableNames.SampleRandom(random);
+      weights =
+        Symbol.GetVariableValues(variableName)
+        .Select(_ => NormalDistributedRandom.NextDouble(random, 0, 1)).ToArray();
+    }
+
+    public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
+      if (random.NextDouble() < 0.2) {
+        VariableName = Symbol.VariableNames.SampleRandom(random);
+        if (weights.Length != Symbol.GetVariableValues(VariableName).Count()) {
+          // if the length of the weight array does not match => re-initialize weights
+          weights =
+            Symbol.GetVariableValues(variableName)
+              .Select(_ => NormalDistributedRandom.NextDouble(random, 0, 1))
+              .ToArray();
+        }
+      } else {
+        // mutate only one randomly selected weight
+        var idx = random.Next(weights.Length);
+        // 50% additive & 50% multiplicative
+        if (random.NextDouble() < 0.5) {
+          double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorMu,
+            Symbol.WeightManipulatorSigma);
+          weights[idx] = weights[idx] + x * shakingFactor;
+        } else {
+          double x = NormalDistributedRandom.NextDouble(random, 1.0, Symbol.MultiplicativeWeightManipulatorSigma);
+          weights[idx] = weights[idx] * x;
+        }
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FactorVariableTreeNode(this, cloner);
+    }
+
+    public double GetValue(string cat) {
+      // TODO: perf
+      var s = Symbol;
+      int idx = 0;
+      foreach (var val in s.GetVariableValues(VariableName)) {
+        if (cat == val) return weights[idx];
+        idx++;
+      }
+      throw new ArgumentOutOfRangeException("Found unknown value " + cat + " for variable " + VariableName);
+    }
+
+    public override string ToString() {
+      return VariableName + "(factor)";
+    }
+  }
+}
+
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs	(revision 14248)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs	(revision 14249)
@@ -187,5 +187,6 @@
     }
 
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable, ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<double> replacementValues) {
+    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable, 
+      ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<double> replacementValues) {
       var originalValues = dataset.GetReadOnlyDoubleValues(variable).ToList();
       dataset.ReplaceVariable(variable, replacementValues.ToList());
@@ -196,5 +197,6 @@
       return estimates;
     }
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable, ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<string> replacementValues) {
+    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable, 
+      ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<string> replacementValues) {
       var originalValues = dataset.GetReadOnlyStringValues(variable).ToList();
       dataset.ReplaceVariable(variable, replacementValues.ToList());
