Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.Designer.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.Designer.cs	(revision 15996)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.Designer.cs	(revision 16435)
@@ -19,4 +19,6 @@
  */
 #endregion
+
+
 namespace HeuristicLab.Problems.DataAnalysis.Views {
   partial class RegressionSolutionVariableImpactsView {
@@ -44,59 +46,76 @@
     /// </summary>
     private void InitializeComponent() {
+      this.ascendingCheckBox = new System.Windows.Forms.CheckBox();
+      this.sortByLabel = new System.Windows.Forms.Label();
+      this.sortByComboBox = new System.Windows.Forms.ComboBox();
+      this.factorVarReplComboBox = new System.Windows.Forms.ComboBox();
+      this.factorVarReplacementLabel = new System.Windows.Forms.Label();
+      this.replacementComboBox = new System.Windows.Forms.ComboBox();
+      this.numericVarReplacementLabel = new System.Windows.Forms.Label();
+      this.dataPartitionLabel = new System.Windows.Forms.Label();
+      this.dataPartitionComboBox = new System.Windows.Forms.ComboBox();
       this.variableImactsArrayView = new HeuristicLab.Data.Views.StringConvertibleArrayView();
-      this.dataPartitionComboBox = new System.Windows.Forms.ComboBox();
-      this.dataPartitionLabel = new System.Windows.Forms.Label();
-      this.numericVarReplacementLabel = new System.Windows.Forms.Label();
-      this.replacementComboBox = new System.Windows.Forms.ComboBox();
-      this.factorVarReplacementLabel = new System.Windows.Forms.Label();
-      this.factorVarReplComboBox = new System.Windows.Forms.ComboBox();
       this.SuspendLayout();
       // 
-      // variableImactsArrayView
-      // 
-      this.variableImactsArrayView.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.variableImactsArrayView.Caption = "StringConvertibleArray View";
-      this.variableImactsArrayView.Content = null;
-      this.variableImactsArrayView.Location = new System.Drawing.Point(3, 84);
-      this.variableImactsArrayView.Name = "variableImactsArrayView";
-      this.variableImactsArrayView.ReadOnly = true;
-      this.variableImactsArrayView.Size = new System.Drawing.Size(363, 278);
-      this.variableImactsArrayView.TabIndex = 2;
-      // 
-      // dataPartitionComboBox
-      // 
-      this.dataPartitionComboBox.FormattingEnabled = true;
-      this.dataPartitionComboBox.Items.AddRange(new object[] {
-            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.Training,
-            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.Test,
-            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.All});
-      this.dataPartitionComboBox.Location = new System.Drawing.Point(197, 3);
-      this.dataPartitionComboBox.Name = "dataPartitionComboBox";
-      this.dataPartitionComboBox.Size = new System.Drawing.Size(121, 21);
-      this.dataPartitionComboBox.TabIndex = 1;
-      this.dataPartitionComboBox.SelectedIndexChanged += new System.EventHandler(this.dataPartitionComboBox_SelectedIndexChanged);
-      // 
-      // dataPartitionLabel
-      // 
-      this.dataPartitionLabel.AutoSize = true;
-      this.dataPartitionLabel.Location = new System.Drawing.Point(3, 6);
-      this.dataPartitionLabel.Name = "dataPartitionLabel";
-      this.dataPartitionLabel.Size = new System.Drawing.Size(73, 13);
-      this.dataPartitionLabel.TabIndex = 0;
-      this.dataPartitionLabel.Text = "Data partition:";
-      // 
-      // numericVarReplacementLabel
-      // 
-      this.numericVarReplacementLabel.AutoSize = true;
-      this.numericVarReplacementLabel.Location = new System.Drawing.Point(3, 33);
-      this.numericVarReplacementLabel.Name = "numericVarReplacementLabel";
-      this.numericVarReplacementLabel.Size = new System.Drawing.Size(173, 13);
-      this.numericVarReplacementLabel.TabIndex = 2;
-      this.numericVarReplacementLabel.Text = "Replacement for numeric variables:";
+      // ascendingCheckBox
+      // 
+      this.ascendingCheckBox.AutoSize = true;
+      this.ascendingCheckBox.Location = new System.Drawing.Point(534, 6);
+      this.ascendingCheckBox.Name = "ascendingCheckBox";
+      this.ascendingCheckBox.Size = new System.Drawing.Size(76, 17);
+      this.ascendingCheckBox.TabIndex = 7;
+      this.ascendingCheckBox.Text = "Ascending";
+      this.ascendingCheckBox.UseVisualStyleBackColor = true;
+      this.ascendingCheckBox.CheckedChanged += new System.EventHandler(this.ascendingCheckBox_CheckedChanged);
+      // 
+      // sortByLabel
+      // 
+      this.sortByLabel.AutoSize = true;
+      this.sortByLabel.Location = new System.Drawing.Point(324, 6);
+      this.sortByLabel.Name = "sortByLabel";
+      this.sortByLabel.Size = new System.Drawing.Size(77, 13);
+      this.sortByLabel.TabIndex = 4;
+      this.sortByLabel.Text = "Sorting criteria:";
+      // 
+      // sortByComboBox
+      // 
+      this.sortByComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.sortByComboBox.FormattingEnabled = true;
+      this.sortByComboBox.Items.AddRange(new object[] {
+            HeuristicLab.Problems.DataAnalysis.Views.RegressionSolutionVariableImpactsView.SortingCriteria.ImpactValue,
+            HeuristicLab.Problems.DataAnalysis.Views.RegressionSolutionVariableImpactsView.SortingCriteria.Occurrence,
+            HeuristicLab.Problems.DataAnalysis.Views.RegressionSolutionVariableImpactsView.SortingCriteria.VariableName});
+      this.sortByComboBox.Location = new System.Drawing.Point(407, 3);
+      this.sortByComboBox.Name = "sortByComboBox";
+      this.sortByComboBox.Size = new System.Drawing.Size(121, 21);
+      this.sortByComboBox.TabIndex = 5;
+      this.sortByComboBox.SelectedIndexChanged += new System.EventHandler(this.sortByComboBox_SelectedIndexChanged);
+      // 
+      // factorVarReplComboBox
+      // 
+      this.factorVarReplComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.factorVarReplComboBox.FormattingEnabled = true;
+      this.factorVarReplComboBox.Items.AddRange(new object[] {
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Best,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Mode,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Shuffle});
+      this.factorVarReplComboBox.Location = new System.Drawing.Point(197, 57);
+      this.factorVarReplComboBox.Name = "factorVarReplComboBox";
+      this.factorVarReplComboBox.Size = new System.Drawing.Size(121, 21);
+      this.factorVarReplComboBox.TabIndex = 1;
+      this.factorVarReplComboBox.SelectedIndexChanged += new System.EventHandler(this.replacementComboBox_SelectedIndexChanged);
+      // 
+      // factorVarReplacementLabel
+      // 
+      this.factorVarReplacementLabel.AutoSize = true;
+      this.factorVarReplacementLabel.Location = new System.Drawing.Point(3, 60);
+      this.factorVarReplacementLabel.Name = "factorVarReplacementLabel";
+      this.factorVarReplacementLabel.Size = new System.Drawing.Size(188, 13);
+      this.factorVarReplacementLabel.TabIndex = 0;
+      this.factorVarReplacementLabel.Text = "Replacement for categorical variables:";
       // 
       // replacementComboBox
       // 
+      this.replacementComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
       this.replacementComboBox.FormattingEnabled = true;
       this.replacementComboBox.Items.AddRange(new object[] {
@@ -111,25 +130,48 @@
       this.replacementComboBox.SelectedIndexChanged += new System.EventHandler(this.replacementComboBox_SelectedIndexChanged);
       // 
-      // factorVarReplacementLabel
-      // 
-      this.factorVarReplacementLabel.AutoSize = true;
-      this.factorVarReplacementLabel.Location = new System.Drawing.Point(3, 60);
-      this.factorVarReplacementLabel.Name = "factorVarReplacementLabel";
-      this.factorVarReplacementLabel.Size = new System.Drawing.Size(188, 13);
-      this.factorVarReplacementLabel.TabIndex = 0;
-      this.factorVarReplacementLabel.Text = "Replacement for categorical variables:";
-      // 
-      // factorVarReplComboBox
-      // 
-      this.factorVarReplComboBox.FormattingEnabled = true;
-      this.factorVarReplComboBox.Items.AddRange(new object[] {
-            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Best,
-            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Mode,
-            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Shuffle});
-      this.factorVarReplComboBox.Location = new System.Drawing.Point(197, 57);
-      this.factorVarReplComboBox.Name = "factorVarReplComboBox";
-      this.factorVarReplComboBox.Size = new System.Drawing.Size(121, 21);
-      this.factorVarReplComboBox.TabIndex = 1;
-      this.factorVarReplComboBox.SelectedIndexChanged += new System.EventHandler(this.replacementComboBox_SelectedIndexChanged);
+      // numericVarReplacementLabel
+      // 
+      this.numericVarReplacementLabel.AutoSize = true;
+      this.numericVarReplacementLabel.Location = new System.Drawing.Point(3, 33);
+      this.numericVarReplacementLabel.Name = "numericVarReplacementLabel";
+      this.numericVarReplacementLabel.Size = new System.Drawing.Size(173, 13);
+      this.numericVarReplacementLabel.TabIndex = 2;
+      this.numericVarReplacementLabel.Text = "Replacement for numeric variables:";
+      // 
+      // dataPartitionLabel
+      // 
+      this.dataPartitionLabel.AutoSize = true;
+      this.dataPartitionLabel.Location = new System.Drawing.Point(3, 6);
+      this.dataPartitionLabel.Name = "dataPartitionLabel";
+      this.dataPartitionLabel.Size = new System.Drawing.Size(73, 13);
+      this.dataPartitionLabel.TabIndex = 0;
+      this.dataPartitionLabel.Text = "Data partition:";
+      // 
+      // dataPartitionComboBox
+      // 
+      this.dataPartitionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.dataPartitionComboBox.FormattingEnabled = true;
+      this.dataPartitionComboBox.Items.AddRange(new object[] {
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.Training,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.Test,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.All});
+      this.dataPartitionComboBox.Location = new System.Drawing.Point(197, 3);
+      this.dataPartitionComboBox.Name = "dataPartitionComboBox";
+      this.dataPartitionComboBox.Size = new System.Drawing.Size(121, 21);
+      this.dataPartitionComboBox.TabIndex = 1;
+      this.dataPartitionComboBox.SelectedIndexChanged += new System.EventHandler(this.dataPartitionComboBox_SelectedIndexChanged);
+      // 
+      // variableImactsArrayView
+      // 
+      this.variableImactsArrayView.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.variableImactsArrayView.Caption = "StringConvertibleArray View";
+      this.variableImactsArrayView.Content = null;
+      this.variableImactsArrayView.Location = new System.Drawing.Point(3, 84);
+      this.variableImactsArrayView.Name = "variableImactsArrayView";
+      this.variableImactsArrayView.ReadOnly = true;
+      this.variableImactsArrayView.Size = new System.Drawing.Size(706, 278);
+      this.variableImactsArrayView.TabIndex = 2;
       // 
       // RegressionSolutionVariableImpactsView
@@ -137,4 +179,7 @@
       this.AllowDrop = true;
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.ascendingCheckBox);
+      this.Controls.Add(this.sortByLabel);
+      this.Controls.Add(this.sortByComboBox);
       this.Controls.Add(this.factorVarReplComboBox);
       this.Controls.Add(this.factorVarReplacementLabel);
@@ -145,5 +190,6 @@
       this.Controls.Add(this.variableImactsArrayView);
       this.Name = "RegressionSolutionVariableImpactsView";
-      this.Size = new System.Drawing.Size(369, 365);
+      this.Size = new System.Drawing.Size(712, 365);
+      this.VisibleChanged += new System.EventHandler(this.RegressionSolutionVariableImpactsView_VisibleChanged);
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -160,4 +206,7 @@
     private System.Windows.Forms.Label factorVarReplacementLabel;
     private System.Windows.Forms.ComboBox factorVarReplComboBox;
+    private System.Windows.Forms.Label sortByLabel;
+    private System.Windows.Forms.ComboBox sortByComboBox;
+    private System.Windows.Forms.CheckBox ascendingCheckBox;
   }
 }
Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs	(revision 15996)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs	(revision 16435)
@@ -19,10 +19,13 @@
  */
 #endregion
+
 using System;
+using System.Collections.Generic;
 using System.Linq;
+using System.Threading;
 using System.Threading.Tasks;
+using HeuristicLab.Common;
 using HeuristicLab.Data;
 using HeuristicLab.MainForm;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -30,4 +33,11 @@
   [Content(typeof(IRegressionSolution))]
   public partial class RegressionSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView {
+    private CancellationTokenSource cancellationToken = new CancellationTokenSource();
+    private enum SortingCriteria {
+      ImpactValue,
+      Occurrence,
+      VariableName
+    }
+    private List<Tuple<string, double>> rawVariableImpacts = new List<Tuple<string, double>>();
 
     public new IRegressionSolution Content {
@@ -41,10 +51,12 @@
       : base() {
       InitializeComponent();
+
+      //Set the default values
       this.dataPartitionComboBox.SelectedIndex = 0;
-      this.replacementComboBox.SelectedIndex = 0;
+      this.replacementComboBox.SelectedIndex = 3;
       this.factorVarReplComboBox.SelectedIndex = 0;
-    }
-
-    #region events
+      this.sortByComboBox.SelectedItem = SortingCriteria.ImpactValue;
+    }
+
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
@@ -72,45 +84,121 @@
         variableImactsArrayView.Content = null;
       } else {
-        UpdateVariableImpacts();
-      }
-    }
-
-    private void UpdateVariableImpacts() {
-      if (Content == null || replacementComboBox.SelectedIndex < 0
-        || factorVarReplComboBox.SelectedIndex < 0
-        || dataPartitionComboBox.SelectedIndex < 0) return;
+        UpdateVariableImpact();
+      }
+    }
+
+    private void RegressionSolutionVariableImpactsView_VisibleChanged(object sender, EventArgs e) {
+      cancellationToken.Cancel();
+    }
+
+
+    private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateVariableImpact();
+    }
+
+    private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateVariableImpact();
+    }
+
+    private void sortByComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      //Update the default ordering (asc,desc), but remove the eventHandler beforehand (otherwise the data would be ordered twice)
+      ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged;
+      ascendingCheckBox.Checked = (SortingCriteria)sortByComboBox.SelectedItem != SortingCriteria.ImpactValue;
+      ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged;
+
+      UpdateOrdering();
+    }
+
+    private void ascendingCheckBox_CheckedChanged(object sender, EventArgs e) {
+      UpdateOrdering();
+    }
+
+
+    private async void UpdateVariableImpact() {
+      IProgress progress;
+
+      //Check if the selection is valid
+      if (Content == null) { return; }
+      if (replacementComboBox.SelectedIndex < 0) { return; }
+      if (dataPartitionComboBox.SelectedIndex < 0) { return; }
+      if (factorVarReplComboBox.SelectedIndex < 0) { return; }
+
+      //Prepare arguments
       var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
+      var replMethod = (RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum)replacementComboBox.Items[replacementComboBox.SelectedIndex];
+      var factorReplMethod = (RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum)factorVarReplComboBox.Items[factorVarReplComboBox.SelectedIndex];
+      var dataPartition = (RegressionSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem;
+
       variableImactsArrayView.Caption = Content.Name + " Variable Impacts";
-      var replMethod =
-         (RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum)
-           replacementComboBox.Items[replacementComboBox.SelectedIndex];
-      var factorReplMethod =
-        (RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum)
-          factorVarReplComboBox.Items[factorVarReplComboBox.SelectedIndex];
-      var dataPartition =
-        (RegressionSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem;
-
-      Task.Factory.StartNew(() => {
-        try {
-          mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
-
-          var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod);
-          var impactArray = new DoubleArray(impacts.Select(i => i.Item2).ToArray());
-          impactArray.ElementNames = impacts.Select(i => i.Item1);
-          variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
-        } finally {
-          mainForm.RemoveOperationProgressFromView(this);
-        }
-      });
-    }
-
-    #endregion
-
-    private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) {
-      UpdateVariableImpacts();
-    }
-
-    private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) {
-      UpdateVariableImpacts();
+      progress = mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
+      progress.ProgressValue = 0;
+
+      cancellationToken = new CancellationTokenSource();
+      //Remember the original ordering of the variables
+      try {
+        var impacts = await Task.Run(() => RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod,
+          (i, s) => {
+            progress.ProgressValue = i;
+            progress.Status = s;
+            return cancellationToken.Token.IsCancellationRequested;
+          }), cancellationToken.Token);
+
+        if (cancellationToken.Token.IsCancellationRequested) { return; }
+        var problemData = Content.ProblemData;
+        var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
+        var originalVariableOrdering = problemData.Dataset.VariableNames
+          .Where(v => inputvariables.Contains(v))
+          .Where(v => problemData.Dataset.VariableHasType<double>(v) || problemData.Dataset.VariableHasType<string>(v))
+          .ToList();
+
+        rawVariableImpacts.Clear();
+        originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(new Tuple<string, double>(v, impacts.First(vv => vv.Item1 == v).Item2)));
+        UpdateOrdering();
+      } finally {
+        ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).RemoveOperationProgressFromView(this);
+      }
+    }
+
+    /// <summary>
+    /// Updates the <see cref="variableImactsArrayView"/> according to the selected ordering <see cref="ascendingCheckBox"/> of the selected Column <see cref="sortByComboBox"/>
+    /// The default is "Descending" by "VariableImpact" (as in previous versions)
+    /// </summary>
+    private void UpdateOrdering() {
+      //Check if valid sortingCriteria is selected and data exists
+      if (sortByComboBox.SelectedIndex == -1) { return; }
+      if (rawVariableImpacts == null) { return; }
+      if (!rawVariableImpacts.Any()) { return; }
+
+      var selectedItem = (SortingCriteria)sortByComboBox.SelectedItem;
+      bool ascending = ascendingCheckBox.Checked;
+
+      IEnumerable<Tuple<string, double>> orderedEntries = null;
+
+      //Sort accordingly
+      switch (selectedItem) {
+        case SortingCriteria.ImpactValue:
+          orderedEntries = rawVariableImpacts.OrderBy(v => v.Item2);
+          break;
+        case SortingCriteria.Occurrence:
+          orderedEntries = rawVariableImpacts;
+          break;
+        case SortingCriteria.VariableName:
+          orderedEntries = rawVariableImpacts.OrderBy(v => v.Item1, new NaturalStringComparer());
+          break;
+        default:
+          throw new NotImplementedException("Ordering for selected SortingCriteria not implemented");
+      }
+
+      if (!ascending) { orderedEntries = orderedEntries.Reverse(); }
+
+      //Write the data back
+      var impactArray = new DoubleArray(orderedEntries.Select(i => i.Item2).ToArray()) {
+        ElementNames = orderedEntries.Select(i => i.Item1)
+      };
+
+      //Could be, if the View was closed
+      if (!variableImactsArrayView.IsDisposed) {
+        variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
+      }
     }
   }
