Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/RunCollectionVariableImpactView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/RunCollectionVariableImpactView.Designer.cs	(revision 7178)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/RunCollectionVariableImpactView.Designer.cs	(revision 7179)
@@ -47,5 +47,5 @@
       this.matrixView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
       this.comboBox = new System.Windows.Forms.ComboBox();
-      this.label1 = new System.Windows.Forms.Label();
+      this.foldsLabel = new System.Windows.Forms.Label();
       this.variableImpactsGroupBox = new System.Windows.Forms.GroupBox();
       this.variableImpactsGroupBox.SuspendLayout();
@@ -54,7 +54,7 @@
       // matrixView
       // 
-      this.matrixView.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.matrixView.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.matrixView.Caption = "StringConvertibleMatrix View";
       this.matrixView.Content = null;
@@ -78,16 +78,16 @@
       // label1
       // 
-      this.label1.AutoSize = true;
-      this.label1.Location = new System.Drawing.Point(3, 9);
-      this.label1.Name = "label1";
-      this.label1.Size = new System.Drawing.Size(30, 13);
-      this.label1.TabIndex = 2;
-      this.label1.Text = "Fold:";
+      this.foldsLabel.AutoSize = true;
+      this.foldsLabel.Location = new System.Drawing.Point(3, 9);
+      this.foldsLabel.Name = "foldsLabel";
+      this.foldsLabel.Size = new System.Drawing.Size(30, 13);
+      this.foldsLabel.TabIndex = 2;
+      this.foldsLabel.Text = "Fold:";
       // 
       // variableImpactsGroupBox
       // 
-      this.variableImpactsGroupBox.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.variableImpactsGroupBox.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.variableImpactsGroupBox.Controls.Add(this.matrixView);
       this.variableImpactsGroupBox.Location = new System.Drawing.Point(0, 33);
@@ -103,5 +103,5 @@
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.Controls.Add(this.variableImpactsGroupBox);
-      this.Controls.Add(this.label1);
+      this.Controls.Add(this.foldsLabel);
       this.Controls.Add(this.comboBox);
       this.Name = "RunCollectionVariableImpactView";
@@ -117,5 +117,5 @@
     private HeuristicLab.Data.Views.StringConvertibleMatrixView matrixView;
     private System.Windows.Forms.ComboBox comboBox;
-    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label foldsLabel;
     private System.Windows.Forms.GroupBox variableImpactsGroupBox;
   }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/RunCollectionVariableImpactView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/RunCollectionVariableImpactView.cs	(revision 7178)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/RunCollectionVariableImpactView.cs	(revision 7179)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using System.Windows.Forms;
@@ -49,25 +50,25 @@
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
-      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
-      Content.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
-      Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
-      Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.UpdateOfRunsInProgressChanged += Content_UpdateOfRunsInProgressChanged;
+      Content.ItemsAdded += Content_ItemsAdded;
+      Content.ItemsRemoved += Content_ItemsRemoved;
+      Content.CollectionReset += Content_CollectionReset;
       RegisterRunEvents(Content);
     }
     protected override void DeregisterContentEvents() {
       base.RegisterContentEvents();
-      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
-      Content.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
-      Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
-      Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.UpdateOfRunsInProgressChanged -= Content_UpdateOfRunsInProgressChanged;
+      Content.ItemsAdded -= Content_ItemsAdded;
+      Content.ItemsRemoved -= Content_ItemsRemoved;
+      Content.CollectionReset -= Content_CollectionReset;
       DeregisterRunEvents(Content);
     }
     private void RegisterRunEvents(IEnumerable<IRun> runs) {
       foreach (IRun run in runs)
-        run.Changed += new EventHandler(Run_Changed);
+        run.Changed += Run_Changed;
     }
     private void DeregisterRunEvents(IEnumerable<IRun> runs) {
       foreach (IRun run in runs)
-        run.Changed -= new EventHandler(Run_Changed);
+        run.Changed -= Run_Changed;
     }
     private void Content_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
@@ -99,20 +100,19 @@
     private void comboBox_SelectedValueChanged(object sender, EventArgs e) {
       if (comboBox.SelectedItem != null) {
-        var cvRuns = from r in Content
-                     where r.Visible
-                     where r.Parameters.ContainsKey(numberOfFoldsParameterName)
-                     select r;
+        var visibleRuns = from run in Content where run.Visible select run;
         if (comboBox.SelectedIndex == 0) {
-          var selectedFolds = cvRuns
-            .SelectMany(r => (RunCollection)r.Results[crossValidationFoldsResultName])
-            .Where(r => r.Results.ContainsKey(variableImpactResultName));
-          matrixView.Content = CalculateVariableImpactMatrix(selectedFolds.ToArray());
+          var selectedFolds = from r in visibleRuns
+                              let foldCollection = (RunCollection)r.Results[crossValidationFoldsResultName]
+                              from run in foldCollection
+                              let name = (r.Name + " " + run.Name)
+                              select new { run, name };
+          matrixView.Content = CalculateVariableImpactMatrix(selectedFolds.Select(x => x.run).ToArray(), selectedFolds.Select(x => x.name).ToArray());
         } else {
-          var selectedFolds = from r in cvRuns
+          var selectedFolds = from r in visibleRuns
                               let foldCollection = (RunCollection)r.Results[crossValidationFoldsResultName]
                               let run = foldCollection.ElementAt(comboBox.SelectedIndex - 1)
-                              where run.Results.ContainsKey(variableImpactResultName)
-                              select new { run, r.Name };
-          matrixView.Content = CalculateVariableImpactMatrix(selectedFolds.Select(x => x.run).ToArray(), selectedFolds.Select(x => x.Name).ToArray());
+                              let name = (r.Name + " " + run.Name)
+                              select new { run, name };
+          matrixView.Content = CalculateVariableImpactMatrix(selectedFolds.Select(x => x.run).ToArray(), selectedFolds.Select(x => x.name).ToArray());
         }
       }
@@ -121,15 +121,52 @@
 
     private void UpdateData() {
-      if (Content != null) {
-        comboBox.Items.Clear();
-        comboBox.Enabled = false;
-        var visibleRuns = Content.Where(r => r.Visible).ToArray();
-        var representativeCvRun =
-          visibleRuns.Where(r => r.Parameters.ContainsKey(numberOfFoldsParameterName)).FirstOrDefault();
-        if (representativeCvRun != null) {
-          // make sure all runs have the same number of folds
-          int nFolds = ((IntValue)representativeCvRun.Parameters[numberOfFoldsParameterName]).Value;
-          var cvRuns = visibleRuns.Where(r => r.Parameters.ContainsKey(numberOfFoldsParameterName));
-          if (cvRuns.All(r => ((IntValue)r.Parameters[numberOfFoldsParameterName]).Value == nFolds)) {
+      if (InvokeRequired) {
+        Invoke((Action)UpdateData);
+      } else {
+        if (Content != null) {
+          comboBox.Items.Clear();
+          comboBox.Enabled = false;
+          comboBox.Visible = false;
+          foldsLabel.Visible = false;
+          variableImpactsGroupBox.Dock = DockStyle.Fill;
+          var visibleRuns = Content.Where(r => r.Visible).ToArray();
+          if (visibleRuns.Length == 0) {
+            DisplayMessage("Run collection is empty.");
+          } else if (visibleRuns.All(r => r.Parameters.ContainsKey(numberOfFoldsParameterName))) {
+            // check if all runs are comparable (CV or normal runs)
+            CheckAndUpdateCvRuns();
+          } else if (visibleRuns.All(r => !r.Parameters.ContainsKey(numberOfFoldsParameterName))) {
+            CheckAndUpdateNormalRuns();
+          } else {
+            // there is a mix of CV and normal runs => show an error message
+            DisplayMessage("The run collection contains a mixture of normal runs and cross-validation runs. Variable impact calculation does not work in this case.");
+          }
+        }
+      }
+    }
+
+    private void CheckAndUpdateCvRuns() {
+      var visibleRuns = from run in Content where run.Visible select run;
+      var representativeRun = visibleRuns.First();
+      // make sure all runs have the same number of folds
+      int nFolds = ((IntValue)representativeRun.Parameters[numberOfFoldsParameterName]).Value;
+      if (visibleRuns.All(r => ((IntValue)r.Parameters[numberOfFoldsParameterName]).Value == nFolds)) {
+        var allFoldResults = visibleRuns.SelectMany(run => (RunCollection)run.Results[crossValidationFoldsResultName]);
+
+        // make sure each fold contains variable impacts 
+        if (!allFoldResults.All(r => r.Results.ContainsKey(variableImpactResultName))) {
+          DisplayMessage("At least one of the runs does not contain a variable impact result.");
+        } else {
+          // make sure each of the runs has the same input variables
+          var allVariableNames = from run in allFoldResults
+                                 let varImpacts = (DoubleMatrix)run.Results[variableImpactResultName]
+                                 select varImpacts.RowNames;
+          var groupedVariableNames = allVariableNames
+            .SelectMany(x => x)
+            .GroupBy(x => x);
+
+          if (groupedVariableNames.Any(g => g.Count() != allFoldResults.Count())) {
+            DisplayMessage("At least one of the runs has a different input variable set than the rest.");
+          } else {
             // populate combobox
             comboBox.Items.Add("Overall");
@@ -139,16 +176,47 @@
             comboBox.SelectedIndex = 0;
             comboBox.Enabled = true;
-          } else {
-            matrixView.Content = null;
-          }
+            comboBox.Visible = true;
+            foldsLabel.Visible = true;
+            variableImpactsGroupBox.Controls.Clear();
+            variableImpactsGroupBox.Dock = DockStyle.None;
+            variableImpactsGroupBox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right |
+                                             AnchorStyles.Bottom;
+            variableImpactsGroupBox.Height = this.Height - comboBox.Height - 12;
+            variableImpactsGroupBox.Width = this.Width;
+            matrixView.Dock = DockStyle.Fill;
+            variableImpactsGroupBox.Controls.Add(matrixView);
+          }
+        }
+      } else {
+        DisplayMessage("At least on of the cross-validation runs has a different number of folds than the rest.");
+      }
+    }
+
+    private void CheckAndUpdateNormalRuns() {
+      // make sure all runs contain variable impact results
+      var visibleRuns = from run in Content where run.Visible select run;
+
+      if (!visibleRuns.All(r => r.Results.ContainsKey(variableImpactResultName))) {
+        DisplayMessage("At least one of the runs does not contain a variable impact result.");
+      } else {
+        // make sure each of the runs has the same input variables
+        var allVariableNames = from run in visibleRuns
+                               let varImpacts = (DoubleMatrix)run.Results[variableImpactResultName]
+                               select varImpacts.RowNames;
+        var groupedVariableNames = allVariableNames
+          .SelectMany(x => x)
+          .GroupBy(x => x);
+
+        if (groupedVariableNames.Any(g => g.Count() != visibleRuns.Count())) {
+          DisplayMessage("At least one of the runs has a different input variable set than the rest.");
         } else {
-          var runsWithVariables = visibleRuns.Where(r => r.Results.ContainsKey(variableImpactResultName)).ToArray();
-          matrixView.Content = CalculateVariableImpactMatrix(runsWithVariables);
-        }
-      }
-    }
-
-    private IStringConvertibleMatrix CalculateVariableImpactMatrix(IRun[] runs) {
-      return CalculateVariableImpactMatrix(runs, runs.Select(r => r.Name).ToArray());
+          if (!variableImpactsGroupBox.Controls.Contains(matrixView)) {
+            variableImpactsGroupBox.Controls.Clear();
+            matrixView.Dock = DockStyle.Fill;
+            variableImpactsGroupBox.Controls.Add(matrixView);
+          }
+          matrixView.Content = CalculateVariableImpactMatrix(visibleRuns.ToArray(), visibleRuns.Select(r => r.Name).ToArray());
+        }
+      }
     }
 
@@ -280,4 +348,9 @@
     }
 
+    private void DisplayMessage(string message) {
+      variableImpactsGroupBox.Controls.Remove(matrixView);
+      var label = new Label { TextAlign = ContentAlignment.MiddleCenter, Text = message, Dock = DockStyle.Fill };
+      variableImpactsGroupBox.Controls.Add(label);
+    }
   }
 }
