Index: /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/CrossValidationView.Designer.cs
===================================================================
--- /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/CrossValidationView.Designer.cs	(revision 12799)
+++ /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/CrossValidationView.Designer.cs	(revision 12800)
@@ -46,4 +46,5 @@
     /// </summary>
     private void InitializeComponent() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CrossValidationView));
       this.startButton = new System.Windows.Forms.Button();
       this.pauseButton = new System.Windows.Forms.Button();
@@ -79,4 +80,6 @@
       this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
       this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.partitionVariableComboBox = new System.Windows.Forms.ComboBox();
+      this.partitionVariableLabel = new System.Windows.Forms.Label();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       ((System.ComponentModel.ISupportInitialize)(this.foldsNumericUpDown)).BeginInit();
@@ -109,5 +112,5 @@
       // 
       this.startButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.startButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Play;
+      this.startButton.Image = ((System.Drawing.Image)(resources.GetObject("startButton.Image")));
       this.startButton.Location = new System.Drawing.Point(0, 514);
       this.startButton.Name = "startButton";
@@ -120,5 +123,5 @@
       // 
       this.pauseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.pauseButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Pause;
+      this.pauseButton.Image = ((System.Drawing.Image)(resources.GetObject("pauseButton.Image")));
       this.pauseButton.Location = new System.Drawing.Point(30, 514);
       this.pauseButton.Name = "pauseButton";
@@ -131,5 +134,5 @@
       // 
       this.stopButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.stopButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Stop;
+      this.stopButton.Image = ((System.Drawing.Image)(resources.GetObject("stopButton.Image")));
       this.stopButton.Location = new System.Drawing.Point(60, 514);
       this.stopButton.Name = "stopButton";
@@ -142,5 +145,5 @@
       // 
       this.resetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.resetButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Restart;
+      this.resetButton.Image = ((System.Drawing.Image)(resources.GetObject("resetButton.Image")));
       this.resetButton.Location = new System.Drawing.Point(90, 514);
       this.resetButton.Name = "resetButton";
@@ -171,7 +174,7 @@
       // foldsNumericUpDown
       // 
-      this.foldsNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
-      this.foldsNumericUpDown.Location = new System.Drawing.Point(55, 26);
+      this.foldsNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.foldsNumericUpDown.Location = new System.Drawing.Point(62, 26);
       this.foldsNumericUpDown.Maximum = new decimal(new int[] {
             50,
@@ -185,5 +188,5 @@
             0});
       this.foldsNumericUpDown.Name = "foldsNumericUpDown";
-      this.foldsNumericUpDown.Size = new System.Drawing.Size(248, 20);
+      this.foldsNumericUpDown.Size = new System.Drawing.Size(241, 20);
       this.foldsNumericUpDown.TabIndex = 3;
       this.foldsNumericUpDown.ThousandsSeparator = true;
@@ -207,7 +210,7 @@
       // workersNumericUpDown
       // 
-      this.workersNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
-      this.workersNumericUpDown.Location = new System.Drawing.Point(55, 0);
+      this.workersNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.workersNumericUpDown.Location = new System.Drawing.Point(62, 0);
       this.workersNumericUpDown.Maximum = new decimal(new int[] {
             50,
@@ -221,5 +224,5 @@
             0});
       this.workersNumericUpDown.Name = "workersNumericUpDown";
-      this.workersNumericUpDown.Size = new System.Drawing.Size(248, 20);
+      this.workersNumericUpDown.Size = new System.Drawing.Size(241, 20);
       this.workersNumericUpDown.TabIndex = 1;
       this.workersNumericUpDown.ThousandsSeparator = true;
@@ -248,5 +251,5 @@
       this.samplesStartLabel.Size = new System.Drawing.Size(75, 13);
       this.samplesStartLabel.TabIndex = 0;
-      this.samplesStartLabel.Text = "&Samples Start:";
+      this.samplesStartLabel.Text = "Samples &Start:";
       // 
       // samplesEndLabel
@@ -257,10 +260,10 @@
       this.samplesEndLabel.Size = new System.Drawing.Size(72, 13);
       this.samplesEndLabel.TabIndex = 2;
-      this.samplesEndLabel.Text = "&Samples End:";
+      this.samplesEndLabel.Text = "Samples &End:";
       // 
       // samplesEndStringConvertibleValueView
       // 
-      this.samplesEndStringConvertibleValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.samplesEndStringConvertibleValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.samplesEndStringConvertibleValueView.Caption = "StringConvertibleValue View";
       this.samplesEndStringConvertibleValueView.Content = null;
@@ -274,6 +277,6 @@
       // samplesStartStringConvertibleValueView
       // 
-      this.samplesStartStringConvertibleValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.samplesStartStringConvertibleValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.samplesStartStringConvertibleValueView.Caption = "StringConvertibleValue View";
       this.samplesStartStringConvertibleValueView.Content = null;
@@ -288,15 +291,15 @@
       // 
       this.tabControl.AllowDrop = true;
-      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-                  | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.tabControl.Controls.Add(this.algorithmTabPage);
       this.tabControl.Controls.Add(this.resultsTabPage);
       this.tabControl.Controls.Add(this.runsTabPage);
-      this.tabControl.Location = new System.Drawing.Point(0, 87);
+      this.tabControl.Location = new System.Drawing.Point(0, 109);
       this.tabControl.Name = "tabControl";
       this.tabControl.SelectedIndex = 0;
-      this.tabControl.Size = new System.Drawing.Size(616, 421);
-      this.tabControl.TabIndex = 4;
+      this.tabControl.Size = new System.Drawing.Size(616, 399);
+      this.tabControl.TabIndex = 5;
       // 
       // algorithmTabPage
@@ -310,5 +313,5 @@
       this.algorithmTabPage.Name = "algorithmTabPage";
       this.algorithmTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.algorithmTabPage.Size = new System.Drawing.Size(608, 395);
+      this.algorithmTabPage.Size = new System.Drawing.Size(608, 373);
       this.algorithmTabPage.TabIndex = 0;
       this.algorithmTabPage.Text = "Algorithm";
@@ -320,6 +323,6 @@
       // algorithmNamedItemView
       // 
-      this.algorithmNamedItemView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmNamedItemView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.algorithmNamedItemView.Caption = "NamedItem View";
       this.algorithmNamedItemView.Content = null;
@@ -333,7 +336,7 @@
       // 
       this.algorithmTabControl.AllowDrop = true;
-      this.algorithmTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-                  | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.algorithmTabControl.Controls.Add(this.algorithmProblemTabPage);
       this.algorithmTabControl.Controls.Add(this.algorithmParametersTabPage);
@@ -341,5 +344,5 @@
       this.algorithmTabControl.Name = "algorithmTabControl";
       this.algorithmTabControl.SelectedIndex = 0;
-      this.algorithmTabControl.Size = new System.Drawing.Size(594, 324);
+      this.algorithmTabControl.Size = new System.Drawing.Size(594, 302);
       this.algorithmTabControl.TabIndex = 3;
       // 
@@ -353,5 +356,5 @@
       this.algorithmProblemTabPage.Name = "algorithmProblemTabPage";
       this.algorithmProblemTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.algorithmProblemTabPage.Size = new System.Drawing.Size(586, 298);
+      this.algorithmProblemTabPage.Size = new System.Drawing.Size(586, 276);
       this.algorithmProblemTabPage.TabIndex = 0;
       this.algorithmProblemTabPage.Text = "Problem";
@@ -363,5 +366,5 @@
       // openProblemButton
       // 
-      this.openProblemButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
+      this.openProblemButton.Image = ((System.Drawing.Image)(resources.GetObject("openProblemButton.Image")));
       this.openProblemButton.Location = new System.Drawing.Point(36, 6);
       this.openProblemButton.Name = "openProblemButton";
@@ -374,7 +377,7 @@
       // algorithmProblemViewHost
       // 
-      this.algorithmProblemViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-                  | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmProblemViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.algorithmProblemViewHost.Caption = "View";
       this.algorithmProblemViewHost.Content = null;
@@ -383,5 +386,5 @@
       this.algorithmProblemViewHost.Name = "algorithmProblemViewHost";
       this.algorithmProblemViewHost.ReadOnly = false;
-      this.algorithmProblemViewHost.Size = new System.Drawing.Size(574, 256);
+      this.algorithmProblemViewHost.Size = new System.Drawing.Size(574, 234);
       this.algorithmProblemViewHost.TabIndex = 2;
       this.algorithmProblemViewHost.ViewsLabelVisible = true;
@@ -390,5 +393,5 @@
       // newProblemButton
       // 
-      this.newProblemButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.NewDocument;
+      this.newProblemButton.Image = ((System.Drawing.Image)(resources.GetObject("newProblemButton.Image")));
       this.newProblemButton.Location = new System.Drawing.Point(6, 6);
       this.newProblemButton.Name = "newProblemButton";
@@ -405,5 +408,5 @@
       this.algorithmParametersTabPage.Name = "algorithmParametersTabPage";
       this.algorithmParametersTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.algorithmParametersTabPage.Size = new System.Drawing.Size(586, 298);
+      this.algorithmParametersTabPage.Size = new System.Drawing.Size(586, 276);
       this.algorithmParametersTabPage.TabIndex = 1;
       this.algorithmParametersTabPage.Text = "Parameters";
@@ -412,4 +415,5 @@
       // algorithmParameterCollectionView
       // 
+      this.algorithmParameterCollectionView.AllowEditingOfHiddenParameters = true;
       this.algorithmParameterCollectionView.Caption = "ParameterCollection View";
       this.algorithmParameterCollectionView.Content = null;
@@ -418,10 +422,11 @@
       this.algorithmParameterCollectionView.Name = "algorithmParameterCollectionView";
       this.algorithmParameterCollectionView.ReadOnly = false;
-      this.algorithmParameterCollectionView.Size = new System.Drawing.Size(580, 292);
+      this.algorithmParameterCollectionView.ShowDetails = true;
+      this.algorithmParameterCollectionView.Size = new System.Drawing.Size(580, 270);
       this.algorithmParameterCollectionView.TabIndex = 0;
       // 
       // openAlgorithmButton
       // 
-      this.openAlgorithmButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
+      this.openAlgorithmButton.Image = ((System.Drawing.Image)(resources.GetObject("openAlgorithmButton.Image")));
       this.openAlgorithmButton.Location = new System.Drawing.Point(38, 6);
       this.openAlgorithmButton.Name = "openAlgorithmButton";
@@ -434,5 +439,5 @@
       // newAlgorithmButton
       // 
-      this.newAlgorithmButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.NewDocument;
+      this.newAlgorithmButton.Image = ((System.Drawing.Image)(resources.GetObject("newAlgorithmButton.Image")));
       this.newAlgorithmButton.Location = new System.Drawing.Point(8, 6);
       this.newAlgorithmButton.Name = "newAlgorithmButton";
@@ -449,5 +454,5 @@
       this.resultsTabPage.Name = "resultsTabPage";
       this.resultsTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.resultsTabPage.Size = new System.Drawing.Size(608, 395);
+      this.resultsTabPage.Size = new System.Drawing.Size(608, 373);
       this.resultsTabPage.TabIndex = 1;
       this.resultsTabPage.Text = "Results";
@@ -462,5 +467,6 @@
       this.resultCollectionView.Name = "resultCollectionView";
       this.resultCollectionView.ReadOnly = true;
-      this.resultCollectionView.Size = new System.Drawing.Size(602, 389);
+      this.resultCollectionView.ShowDetails = true;
+      this.resultCollectionView.Size = new System.Drawing.Size(602, 367);
       this.resultCollectionView.TabIndex = 0;
       // 
@@ -472,5 +478,5 @@
       this.runsTabPage.Name = "runsTabPage";
       this.runsTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.runsTabPage.Size = new System.Drawing.Size(608, 395);
+      this.runsTabPage.Size = new System.Drawing.Size(608, 373);
       this.runsTabPage.TabIndex = 2;
       this.runsTabPage.Text = "Runs";
@@ -501,5 +507,5 @@
       this.runCollectionView.Name = "runCollectionView";
       this.runCollectionView.ReadOnly = false;
-      this.runCollectionView.Size = new System.Drawing.Size(602, 389);
+      this.runCollectionView.Size = new System.Drawing.Size(602, 367);
       this.runCollectionView.TabIndex = 0;
       // 
@@ -513,6 +519,6 @@
       // splitContainer
       // 
-      this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
       this.splitContainer.Location = new System.Drawing.Point(0, 26);
       this.splitContainer.Name = "splitContainer";
@@ -527,15 +533,38 @@
       // splitContainer.Panel2
       // 
+      this.splitContainer.Panel2.Controls.Add(this.partitionVariableComboBox);
+      this.splitContainer.Panel2.Controls.Add(this.partitionVariableLabel);
       this.splitContainer.Panel2.Controls.Add(this.foldsNumericUpDown);
       this.splitContainer.Panel2.Controls.Add(this.foldsLabel);
       this.splitContainer.Panel2.Controls.Add(this.workersLabel);
       this.splitContainer.Panel2.Controls.Add(this.workersNumericUpDown);
-      this.splitContainer.Size = new System.Drawing.Size(616, 55);
+      this.splitContainer.Size = new System.Drawing.Size(616, 77);
       this.splitContainer.SplitterDistance = 306;
       this.splitContainer.TabIndex = 3;
       // 
+      // partitionVariableComboBox
+      // 
+      this.partitionVariableComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.partitionVariableComboBox.FormattingEnabled = true;
+      this.partitionVariableComboBox.Items.AddRange(new object[] {
+            "<none>"});
+      this.partitionVariableComboBox.Location = new System.Drawing.Point(62, 52);
+      this.partitionVariableComboBox.Name = "partitionVariableComboBox";
+      this.partitionVariableComboBox.Size = new System.Drawing.Size(241, 21);
+      this.partitionVariableComboBox.TabIndex = 4;
+      this.partitionVariableComboBox.SelectionChangeCommitted += new System.EventHandler(this.partitionVariableComboBox_SelectionChangeCommitted);
+      // 
+      // partitionVariableLabel
+      // 
+      this.partitionVariableLabel.AutoSize = true;
+      this.partitionVariableLabel.Location = new System.Drawing.Point(3, 55);
+      this.partitionVariableLabel.Name = "partitionVariableLabel";
+      this.partitionVariableLabel.Size = new System.Drawing.Size(53, 13);
+      this.partitionVariableLabel.TabIndex = 4;
+      this.partitionVariableLabel.Text = "&Partitions:";
+      // 
       // CrossValidationView
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
       this.Controls.Add(this.tabControl);
@@ -617,4 +646,6 @@
     private System.Windows.Forms.SplitContainer splitContainer;
     private Optimization.Views.ResultCollectionView resultCollectionView;
+    private System.Windows.Forms.ComboBox partitionVariableComboBox;
+    private System.Windows.Forms.Label partitionVariableLabel;
   }
 }
Index: /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/CrossValidationView.cs
===================================================================
--- /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/CrossValidationView.cs	(revision 12799)
+++ /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/CrossValidationView.cs	(revision 12800)
@@ -64,5 +64,5 @@
         Locked = ReadOnly = Content.ExecutionState == ExecutionState.Started;
         workersNumericUpDown.Value = Content.NumberOfWorkers.Value;
-        foldsNumericUpDown.Value = Content.Folds.Value;
+        foldsNumericUpDown.Value = Content.Folds;
         samplesStartStringConvertibleValueView.Content = Content.SamplesStart;
         samplesEndStringConvertibleValueView.Content = Content.SamplesEnd;
@@ -81,5 +81,6 @@
       Content.AlgorithmChanged += new EventHandler(Content_AlgorithmChanged);
       Content.ProblemChanged += new EventHandler(Content_ProblemChanged);
-      Content.Folds.ValueChanged += new EventHandler(Content_Folds_ValueChanged);
+      if (Content.Problem != null) Content.Problem.Reset += Content_ProblemReset;
+      Content.FoldsChanged += Content_FoldsChanged;
       Content.NumberOfWorkers.ValueChanged += new EventHandler(Content_NumberOfWorker_ValueChanged);
 
@@ -93,5 +94,6 @@
       Content.AlgorithmChanged -= new EventHandler(Content_AlgorithmChanged);
       Content.ProblemChanged -= new EventHandler(Content_ProblemChanged);
-      Content.Folds.ValueChanged -= new EventHandler(Content_Folds_ValueChanged);
+      if (Content.Problem != null) Content.Problem.Reset -= Content_ProblemReset;
+      Content.FoldsChanged -= Content_FoldsChanged;
       Content.NumberOfWorkers.ValueChanged -= new EventHandler(Content_NumberOfWorker_ValueChanged);
 
@@ -132,4 +134,6 @@
           samplesEndStringConvertibleValueView.Enabled = Content.ExecutionState == ExecutionState.Prepared;
           workersNumericUpDown.Enabled = (Content.ExecutionState == ExecutionState.Prepared) || (Content.ExecutionState == ExecutionState.Paused);
+          partitionVariableLabel.Enabled = (Content.ExecutionState == ExecutionState.Prepared);
+          partitionVariableComboBox.Enabled = (Content.ExecutionState == ExecutionState.Prepared);
 
           startButton.Enabled = (Content.ExecutionState == ExecutionState.Prepared) || (Content.ExecutionState == ExecutionState.Paused);
@@ -144,23 +148,63 @@
     private void Content_AlgorithmChanged(object sender, EventArgs e) {
       UpdateAlgorithmView();
+      UpdateFolds();
       UpdateProblemView();
       SetEnabledStateOfControls();
     }
     private void UpdateAlgorithmView() {
-      algorithmNamedItemView.Content = Content.Algorithm;
-      UpdateProblemView();
+      if (InvokeRequired) Invoke((Action)UpdateAlgorithmView);
+      else {
+        algorithmNamedItemView.Content = Content.Algorithm;
+        UpdateProblemView();
+      }
     }
 
     private void Content_ProblemChanged(object sender, EventArgs e) {
+      if (Content.Problem != null) Content.Problem.Reset += Content_ProblemReset;
+      UpdateFolds();
       UpdateProblemView();
       SetEnabledStateOfControls();
     }
+
+    private void Content_ProblemReset(object sender, EventArgs e) {
+      UpdateFolds();
+    }
+
+
     private void UpdateProblemView() {
-      algorithmProblemViewHost.Content = Content.Problem;
-    }
-
-    private void Content_Folds_ValueChanged(object sender, EventArgs e) {
-      foldsNumericUpDown.Value = Content.Folds.Value;
-    }
+      if (InvokeRequired) Invoke((Action)UpdateProblemView);
+      else {
+        algorithmProblemViewHost.Content = Content.Problem;
+      }
+    }
+
+    private void Content_FoldsChanged(object sender, EventArgs e) {
+      UpdateFolds();
+    }
+
+    private bool disableUpdateToContent = false; // to prevent changing Content.Folds or Content.PartitionVariable while updating the GUI from the content
+    private void UpdateFolds() {
+      if (InvokeRequired) Invoke((Action)UpdateFolds);
+      else {
+        disableUpdateToContent = true;
+        foldsNumericUpDown.Value = Content.Folds;
+
+        partitionVariableComboBox.BeginUpdate();
+        partitionVariableComboBox.Items.Clear();
+        partitionVariableComboBox.Items.Add(CrossValidation.NoPartitionVariable);
+        var ds = Content.Problem.ProblemData.Dataset;
+        var rows = Enumerable.Range(Content.SamplesStart.Value, Content.SamplesEnd.Value - Content.SamplesStart.Value);
+        foreach (var variable in Content.Problem.ProblemData.Dataset.DoubleVariables) {
+          if (Content.Problem.ProblemData.AllowedInputVariables.Contains(variable)) continue;
+          int distinctValues = ds.GetDoubleValues(variable, rows).Distinct().Count();
+          if (distinctValues < 2 || distinctValues > 20) continue;
+          partitionVariableComboBox.Items.Add(variable);
+        }
+        partitionVariableComboBox.SelectedItem = Content.PartitionVariable;
+        partitionVariableComboBox.EndUpdate();
+        disableUpdateToContent = false;
+      }
+    }
+
     private void Content_NumberOfWorker_ValueChanged(object sender, EventArgs e) {
       workersNumericUpDown.Value = Content.NumberOfWorkers.Value;
@@ -202,6 +246,7 @@
     }
     private void foldsNumericUpDown_ValueChanged(object sender, EventArgs e) {
-      if (Content != null)
-        Content.Folds.Value = (int)foldsNumericUpDown.Value;
+      if (Content != null && !disableUpdateToContent) {
+        Content.Folds = (int)foldsNumericUpDown.Value;
+      }
     }
 
@@ -238,6 +283,5 @@
         try {
           Content.Algorithm = (IAlgorithm)algorithmTypeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
-        }
-        catch (Exception ex) {
+        } catch (Exception ex) {
           ErrorHandling.ShowErrorDialog(this, ex);
         }
@@ -258,9 +302,7 @@
             else
               Content.Algorithm = algorithm;
-          }
-          catch (Exception ex) {
+          } catch (Exception ex) {
             ErrorHandling.ShowErrorDialog(this, ex);
-          }
-          finally {
+          } finally {
             Invoke(new Action(delegate() {
               algorithmTabControl.Enabled = true;
@@ -298,9 +340,7 @@
             else
               Content.Problem = problem;
-          }
-          catch (Exception ex) {
+          } catch (Exception ex) {
             Invoke(new Action(() => ErrorHandling.ShowErrorDialog(this, ex)));
-          }
-          finally {
+          } finally {
             Invoke(new Action(delegate() {
               algorithmProblemViewHost.Enabled = true;
@@ -358,4 +398,9 @@
     #endregion
 
+    private void partitionVariableComboBox_SelectionChangeCommitted(object sender, EventArgs e) {
+      // when the user changes the selection in the GUI
+      if (Content != null && !disableUpdateToContent)
+        Content.PartitionVariable = (string)partitionVariableComboBox.SelectedItem;
+    }
   }
 }
Index: /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs
===================================================================
--- /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 12799)
+++ /branches/crossvalidation-2434/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 12800)
@@ -52,5 +52,5 @@
       results = new ResultCollection();
 
-      folds = new IntValue(2);
+      folds = 2;
       numberOfWorkers = new IntValue(1);
       samplesStart = new IntValue(0);
@@ -73,4 +73,9 @@
       RegisterEvents();
       if (Algorithm != null) RegisterAlgorithmEvents();
+
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.6
+      if (persistenceCompatibilityFolds != null) folds = persistenceCompatibilityFolds.Value;
+      #endregion
     }
 
@@ -85,5 +90,5 @@
       results = cloner.Clone(original.results);
 
-      folds = cloner.Clone(original.folds);
+      folds = original.folds;
       numberOfWorkers = cloner.Clone(original.numberOfWorkers);
       samplesStart = cloner.Clone(original.samplesStart);
@@ -171,9 +176,37 @@
     }
 
-    [Storable]
-    private IntValue folds;
-    public IntValue Folds {
+    // BackwardsCompatibility3.4
+    #region Backwards compatible code, remove with 3.6
+    [Storable(Name = "folds")]
+    private IntValue persistenceCompatibilityFolds;
+    #endregion
+
+    [Storable(Name = "foldsNew")]
+    private int folds;
+    public int Folds {
       get { return folds; }
-    }
+      set {
+        if (value != folds) {
+          folds = value;
+          partitionVariable = NoPartitionVariable; // setting folds updates the partition variable
+          OnFoldsChanged();
+        }
+      }
+    }
+
+    [Storable]
+    // folds are either specified explicitly or by a varaible from the dataset 
+    public const string NoPartitionVariable = "<none>";
+    private string partitionVariable = NoPartitionVariable;
+    public string PartitionVariable {
+      get { return partitionVariable; }
+      set {
+        if (value != partitionVariable) {
+          partitionVariable = value;
+          UpdateNumberOfFolds();
+        }
+      }
+    }
+
     [Storable]
     private IntValue samplesStart;
@@ -244,4 +277,5 @@
       }
     }
+
     #endregion
 
@@ -273,7 +307,6 @@
         //create cloned algorithms
         if (clonedAlgorithms.Count == 0) {
-          int testSamplesCount = (SamplesEnd.Value - SamplesStart.Value) / Folds.Value;
-
-          for (int i = 0; i < Folds.Value; i++) {
+
+          for (int i = 0; i < folds; i++) {
             IAlgorithm clonedAlgorithm = (IAlgorithm)algorithm.Clone();
             clonedAlgorithm.Name = algorithm.Name + " Fold " + i;
@@ -281,6 +314,7 @@
             ISymbolicDataAnalysisProblem symbolicProblem = problem as ISymbolicDataAnalysisProblem;
 
-            int testStart = (i * testSamplesCount) + SamplesStart.Value;
-            int testEnd = (i + 1) == Folds.Value ? SamplesEnd.Value : (i + 1) * testSamplesCount + SamplesStart.Value;
+            int trainingStart, trainingEnd, testStart, testEnd;
+            // assumes that partitions are subset of subsequent rows
+            GetTrainingAndTestPartitions(i, out trainingStart, out trainingEnd, out testStart, out testEnd);
 
             problem.ProblemData.TrainingPartition.Start = SamplesStart.Value;
@@ -306,5 +340,5 @@
         int startedAlgorithms = 0;
         foreach (IAlgorithm clonedAlgorithm in clonedAlgorithms) {
-          if (startedAlgorithms < NumberOfWorkers.Value) {
+          if (startedAlgorithms < numberOfWorkers.Value) {
             if (clonedAlgorithm.ExecutionState == ExecutionState.Prepared ||
                 clonedAlgorithm.ExecutionState == ExecutionState.Paused) {
@@ -324,4 +358,23 @@
         }
         OnStarted();
+      }
+    }
+
+    private void GetTrainingAndTestPartitions(int fold, out int trainingStart, out int trainingEnd, out int testStart, out int testEnd) {
+      if (partitionVariable == NoPartitionVariable) {
+        // uniform split
+        int testSamplesCount = (SamplesEnd.Value - SamplesStart.Value) / folds;
+        trainingStart = SamplesStart.Value;
+        trainingEnd = SamplesEnd.Value;
+        testStart = (fold * testSamplesCount) + SamplesStart.Value;
+        testEnd = (fold + 1) == folds ? SamplesEnd.Value : (fold + 1) * testSamplesCount + SamplesStart.Value;
+      } else {
+        // group rowIdx by partition
+        var partition = Problem.ProblemData.Dataset.GetReadOnlyDoubleValues(partitionVariable);
+        var g = Enumerable.Range(SamplesStart.Value, SamplesEnd.Value - SamplesStart.Value).GroupBy(r => partition[r]).OrderBy(r => r.Key).ToList();
+        trainingStart = SamplesStart.Value;
+        trainingEnd = SamplesEnd.Value;
+        testStart = g[fold].Min();
+        testEnd = g[fold].Max() + 1;
       }
     }
@@ -365,5 +418,5 @@
       values.Add("Algorithm Name", new StringValue(Name));
       values.Add("Algorithm Type", new StringValue(GetType().GetPrettyName()));
-      values.Add("Folds", new IntValue(Folds.Value));
+      values.Add("Folds", new IntValue(folds));
 
       if (algorithm != null) {
@@ -516,10 +569,21 @@
     #region events
     private void RegisterEvents() {
-      Folds.ValueChanged += new EventHandler(Folds_ValueChanged);
+      SamplesStart.ValueChanged += (s, e) => UpdateNumberOfFolds();
+      SamplesEnd.ValueChanged += (s, e) => UpdateNumberOfFolds();
+
       RegisterClonedAlgorithmsEvents();
     }
-    private void Folds_ValueChanged(object sender, EventArgs e) {
-      if (ExecutionState != ExecutionState.Prepared)
-        throw new InvalidOperationException("Can not change number of folds if the execution state is not prepared.");
+
+    private void UpdateNumberOfFolds() {
+      if (ExecutionState == ExecutionState.Paused || executionState == ExecutionState.Started)
+        throw new InvalidOperationException("Can not change number of folds if crossvalidation is paused or started.");
+
+      if (partitionVariable != NoPartitionVariable) {
+        // number of folds is the number of distinct values of the partition variable in the range [SamplesStart..SamplesEnd[
+        var ds = Problem.ProblemData.Dataset;
+        var partitionValues = ds.GetDoubleValues(PartitionVariable, Enumerable.Range(SamplesStart.Value, SamplesEnd.Value - SamplesStart.Value)).Distinct().Count();
+        folds = partitionValues;
+        OnFoldsChanged();
+      }
     }
 
@@ -555,7 +619,7 @@
     public event EventHandler ProblemChanged;
     private void OnProblemChanged() {
+      ConfigureProblem();
       EventHandler handler = ProblemChanged;
       if (handler != null) handler(this, EventArgs.Empty);
-      ConfigureProblem();
     }
 
@@ -565,4 +629,6 @@
 
     private void ConfigureProblem() {
+      folds = 2;
+      partitionVariable = NoPartitionVariable;
       SamplesStart.Value = 0;
       if (Problem != null) {
@@ -687,4 +753,10 @@
 
     #region event firing
+
+    public event EventHandler FoldsChanged;
+    private void OnFoldsChanged() {
+      EventHandler handler = FoldsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
     public event EventHandler ExecutionStateChanged;
     private void OnExecutionStateChanged() {
