Index: /branches/GP.Grammar.Editor/HeuristicLab 3.3.sln
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab 3.3.sln	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab 3.3.sln	(revision 6647)
@@ -407,4 +407,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.PluginInfrastructure-3.3.Tests", "HeuristicLab.PluginInfrastructure\3.3\Tests\HeuristicLab.PluginInfrastructure-3.3.Tests.csproj", "{04840E7E-F7DB-4CE4-B308-EE805DD94E73}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3", "HeuristicLab.Problems.QuadraticAssignment.Algorithms\3.3\HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3.csproj", "{5B9B9E8C-2706-43C2-80B8-A08341E431F7}"
 EndProject
 Global
@@ -1873,4 +1875,16 @@
 		{04840E7E-F7DB-4CE4-B308-EE805DD94E73}.Release|x86.ActiveCfg = Release|x86
 		{04840E7E-F7DB-4CE4-B308-EE805DD94E73}.Release|x86.Build.0 = Release|x86
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Debug|x64.ActiveCfg = Debug|x64
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Debug|x64.Build.0 = Debug|x64
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Debug|x86.ActiveCfg = Debug|x86
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Debug|x86.Build.0 = Debug|x86
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Release|x64.ActiveCfg = Release|x64
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Release|x64.Build.0 = Release|x64
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Release|x86.ActiveCfg = Release|x86
+		{5B9B9E8C-2706-43C2-80B8-A08341E431F7}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 6647)
@@ -446,5 +446,5 @@
         // clone models
         var ensembleSolution = new ClassificationEnsembleSolution(
-          solutions.Value.Select(x => cloner.Clone(x.Model)), 
+          solutions.Value.Select(x => cloner.Clone(x.Model)),
           problemDataClone,
           solutions.Value.Select(x => cloner.Clone(x.ProblemData.TrainingPartition)),
@@ -543,4 +543,5 @@
         throw new ArgumentException("A cross validation algorithm can only contain DataAnalysisProblems.");
       }
+      algorithm.Problem.Reset += (x,y) => OnProblemChanged();
       problem = (IDataAnalysisProblem)algorithm.Problem;
       OnProblemChanged();
@@ -553,5 +554,4 @@
       SamplesStart.Value = 0;
       if (Problem != null) {
-        Problem.ProblemDataChanged += (object sender, EventArgs e) => OnProblemChanged();
         SamplesEnd.Value = Problem.ProblemData.Dataset.Rows;
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 6647)
@@ -56,10 +56,10 @@
     }
 
-    #region logit regression
+    #region logit classification
     protected override void Run() {
       double rmsError, relClassError;
       var solution = CreateLogitClassificationSolution(Problem.ProblemData, out rmsError, out relClassError);
-      Results.Add(new Result(LogitClassificationModelResultName, "The linear regression solution.", solution));
-      Results.Add(new Result("Root mean square error", "The root of the mean of squared errors of the logit regression solution on the training set.", new DoubleValue(rmsError)));
+      Results.Add(new Result(LogitClassificationModelResultName, "The logit classification solution.", solution));
+      Results.Add(new Result("Root mean squared error", "The root of the mean of squared errors of the logit regression solution on the training set.", new DoubleValue(rmsError)));
       Results.Add(new Result("Relative classification error", "Relative classification error on the training set (percentage of misclassified cases).", new PercentValue(relClassError)));
     }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 6647)
@@ -66,5 +66,5 @@
       targetVariable = original.targetVariable;
       allowedInputVariables = (string[])original.allowedInputVariables.Clone();
-      this.classValues = (double[])original.classValues.Clone();
+      classValues = (double[])original.classValues.Clone();
     }
     public MultinomialLogitModel(alglib.logitmodel logitModel, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues)
Index: /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/IslandOffspringSelectionGeneticAlgorithmMainLoop.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/IslandOffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/IslandOffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 6647)
@@ -223,6 +223,6 @@
       islandAnalyzer1.OperatorParameter.ActualName = IslandAnalyzerParameter.Name;
 
-      islandResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", null, "SelectionPressure"));
-      islandResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", null, "CurrentSuccessRatio"));
+      islandResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", "Displays the rising selection pressure during a generation.", "SelectionPressure"));
+      islandResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", "Indicates how many successful children were already found during a generation (relative to the population size).", "CurrentSuccessRatio"));
       islandResultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
 
@@ -264,6 +264,6 @@
       islandAnalyzer2.OperatorParameter.ActualName = IslandAnalyzerParameter.Name;
 
-      islandResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", null, "SelectionPressure"));
-      islandResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", null, "CurrentSuccessRatio"));
+      islandResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", "Displays the rising selection pressure during a generation.", "SelectionPressure"));
+      islandResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", "Indicates how many successful children were already found during a generation (relative to the population size).", "CurrentSuccessRatio"));
       islandResultsCollector2.ResultsParameter.ActualName = "Results";
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithmMainLoop.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/OffspringSelectionGeneticAlgorithmMainLoop.cs	(revision 6647)
@@ -161,7 +161,7 @@
       resultsCollector1.CopyValue = new BoolValue(false);
       resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>("Generations"));
-      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Curent Comparison Factor", null, ComparisonFactorParameter.Name));
-      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", null, "SelectionPressure"));
-      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", null, "CurrentSuccessRatio"));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Comparison Factor", null, ComparisonFactorParameter.Name));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", "Displays the rising selection pressure during a generation.", "SelectionPressure"));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", "Indicates how many successful children were already found during a generation (relative to the population size).", "CurrentSuccessRatio"));
       resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/SASEGASAMainLoop.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/SASEGASAMainLoop.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm/3.3/SASEGASAMainLoop.cs	(revision 6647)
@@ -214,6 +214,6 @@
       villageAnalyzer1.OperatorParameter.ActualName = VillageAnalyzerParameter.Name;
 
-      villageResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", null, "CurrentSuccessRatio"));
-      villageResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", null, "SelectionPressure"));
+      villageResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", "Indicates how many successful children were already found during a generation (relative to the population size).", "CurrentSuccessRatio"));
+      villageResultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", "Displays the rising selection pressure during a generation.", "SelectionPressure"));
       villageResultsCollector1.ResultsParameter.ActualName = "Results";
 
@@ -252,6 +252,6 @@
       villageAnalyzer2.OperatorParameter.ActualName = VillageAnalyzerParameter.Name;
 
-      villageResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", null, "CurrentSuccessRatio"));
-      villageResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", null, "SelectionPressure"));
+      villageResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Success Ratio", "Indicates how many successful children were already found during a generation (relative to the population size).", "CurrentSuccessRatio"));
+      villageResultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>("Current Selection Pressure", "Displays the rising selection pressure during a generation.", "SelectionPressure"));
       villageResultsCollector2.ResultsParameter.ActualName = "Results";
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.Designer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.Designer.cs	(revision 6647)
@@ -73,4 +73,6 @@
       this.lineStyleComboBox = new System.Windows.Forms.ComboBox();
       this.label8 = new System.Windows.Forms.Label();
+      this.label9 = new System.Windows.Forms.Label();
+      this.displayNameTextBox = new System.Windows.Forms.TextBox();
       ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).BeginInit();
       this.commonGroupBox.SuspendLayout();
@@ -88,7 +90,7 @@
       this.chartTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
       this.chartTypeComboBox.FormattingEnabled = true;
-      this.chartTypeComboBox.Location = new System.Drawing.Point(76, 19);
+      this.chartTypeComboBox.Location = new System.Drawing.Point(89, 45);
       this.chartTypeComboBox.Name = "chartTypeComboBox";
-      this.chartTypeComboBox.Size = new System.Drawing.Size(224, 21);
+      this.chartTypeComboBox.Size = new System.Drawing.Size(211, 21);
       this.chartTypeComboBox.TabIndex = 1;
       this.chartTypeComboBox.SelectedValueChanged += new System.EventHandler(this.chartTypeComboBox_SelectedValueChanged);
@@ -101,5 +103,5 @@
       // 
       this.colorButton.BackColor = System.Drawing.SystemColors.Control;
-      this.colorButton.Location = new System.Drawing.Point(76, 46);
+      this.colorButton.Location = new System.Drawing.Point(89, 72);
       this.colorButton.Name = "colorButton";
       this.colorButton.Size = new System.Drawing.Size(23, 23);
@@ -140,14 +142,14 @@
       // 
       this.label1.AutoSize = true;
-      this.label1.Location = new System.Drawing.Point(8, 22);
+      this.label1.Location = new System.Drawing.Point(8, 48);
       this.label1.Name = "label1";
-      this.label1.Size = new System.Drawing.Size(62, 13);
+      this.label1.Size = new System.Drawing.Size(58, 13);
       this.label1.TabIndex = 0;
-      this.label1.Text = "Chart Type:";
+      this.label1.Text = "Chart type:";
       // 
       // label2
       // 
       this.label2.AutoSize = true;
-      this.label2.Location = new System.Drawing.Point(8, 51);
+      this.label2.Location = new System.Drawing.Point(8, 77);
       this.label2.Name = "label2";
       this.label2.Size = new System.Drawing.Size(34, 13);
@@ -168,6 +170,8 @@
       this.commonGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                   | System.Windows.Forms.AnchorStyles.Right)));
+      this.commonGroupBox.Controls.Add(this.displayNameTextBox);
       this.commonGroupBox.Controls.Add(this.axisGroupBox);
       this.commonGroupBox.Controls.Add(this.colorButton);
+      this.commonGroupBox.Controls.Add(this.label9);
       this.commonGroupBox.Controls.Add(this.label1);
       this.commonGroupBox.Controls.Add(this.label2);
@@ -175,5 +179,5 @@
       this.commonGroupBox.Location = new System.Drawing.Point(3, 3);
       this.commonGroupBox.Name = "commonGroupBox";
-      this.commonGroupBox.Size = new System.Drawing.Size(313, 158);
+      this.commonGroupBox.Size = new System.Drawing.Size(313, 181);
       this.commonGroupBox.TabIndex = 0;
       this.commonGroupBox.TabStop = false;
@@ -186,10 +190,10 @@
       this.axisGroupBox.Controls.Add(this.panel1);
       this.axisGroupBox.Controls.Add(this.panel2);
-      this.axisGroupBox.Location = new System.Drawing.Point(6, 75);
+      this.axisGroupBox.Location = new System.Drawing.Point(6, 101);
       this.axisGroupBox.Name = "axisGroupBox";
       this.axisGroupBox.Size = new System.Drawing.Size(299, 75);
       this.axisGroupBox.TabIndex = 9;
       this.axisGroupBox.TabStop = false;
-      this.axisGroupBox.Text = "Display Data on";
+      this.axisGroupBox.Text = "Display data on";
       // 
       // label5
@@ -200,5 +204,5 @@
       this.label5.Size = new System.Drawing.Size(39, 13);
       this.label5.TabIndex = 6;
-      this.label5.Text = "Y Axis:";
+      this.label5.Text = "Y-Axis:";
       // 
       // label6
@@ -209,5 +213,5 @@
       this.label6.Size = new System.Drawing.Size(39, 13);
       this.label6.TabIndex = 6;
-      this.label6.Text = "X Axis:";
+      this.label6.Text = "X-Axis:";
       // 
       // panel1
@@ -284,5 +288,5 @@
       this.histoGramGroupBox.Controls.Add(this.binsNumericUpDown);
       this.histoGramGroupBox.Controls.Add(this.label3);
-      this.histoGramGroupBox.Location = new System.Drawing.Point(3, 269);
+      this.histoGramGroupBox.Location = new System.Drawing.Point(3, 292);
       this.histoGramGroupBox.Name = "histoGramGroupBox";
       this.histoGramGroupBox.Size = new System.Drawing.Size(313, 49);
@@ -334,10 +338,10 @@
       this.lineChartGroupBox.Controls.Add(this.lineStyleComboBox);
       this.lineChartGroupBox.Controls.Add(this.label8);
-      this.lineChartGroupBox.Location = new System.Drawing.Point(3, 167);
+      this.lineChartGroupBox.Location = new System.Drawing.Point(3, 190);
       this.lineChartGroupBox.Name = "lineChartGroupBox";
       this.lineChartGroupBox.Size = new System.Drawing.Size(313, 96);
       this.lineChartGroupBox.TabIndex = 1;
       this.lineChartGroupBox.TabStop = false;
-      this.lineChartGroupBox.Text = "Line Chart";
+      this.lineChartGroupBox.Text = "Line chart";
       // 
       // lineWidthNumericUpDown
@@ -364,7 +368,7 @@
       this.label4.Location = new System.Drawing.Point(8, 68);
       this.label4.Name = "label4";
-      this.label4.Size = new System.Drawing.Size(61, 13);
+      this.label4.Size = new System.Drawing.Size(58, 13);
       this.label4.TabIndex = 4;
-      this.label4.Text = "Line Width:";
+      this.label4.Text = "Line width:";
       // 
       // label7
@@ -373,7 +377,7 @@
       this.label7.Location = new System.Drawing.Point(8, 46);
       this.label7.Name = "label7";
-      this.label7.Size = new System.Drawing.Size(82, 13);
+      this.label7.Size = new System.Drawing.Size(81, 13);
       this.label7.TabIndex = 2;
-      this.label7.Text = "Start Index at 0:";
+      this.label7.Text = "Start index at 0:";
       // 
       // lineStyleComboBox
@@ -392,7 +396,24 @@
       this.label8.Location = new System.Drawing.Point(8, 22);
       this.label8.Name = "label8";
-      this.label8.Size = new System.Drawing.Size(56, 13);
+      this.label8.Size = new System.Drawing.Size(54, 13);
       this.label8.TabIndex = 0;
-      this.label8.Text = "Line Style:";
+      this.label8.Text = "Line style:";
+      // 
+      // label9
+      // 
+      this.label9.AutoSize = true;
+      this.label9.Location = new System.Drawing.Point(8, 22);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(75, 13);
+      this.label9.TabIndex = 0;
+      this.label9.Text = "Display Name:";
+      // 
+      // displayNameTextBox
+      // 
+      this.displayNameTextBox.Location = new System.Drawing.Point(89, 19);
+      this.displayNameTextBox.Name = "displayNameTextBox";
+      this.displayNameTextBox.Size = new System.Drawing.Size(211, 20);
+      this.displayNameTextBox.TabIndex = 10;
+      this.displayNameTextBox.Validated += new System.EventHandler(this.displayNameTextBox_Validated);
       // 
       // DataRowVisualPropertiesControl
@@ -404,5 +425,5 @@
       this.Controls.Add(this.commonGroupBox);
       this.Name = "DataRowVisualPropertiesControl";
-      this.Size = new System.Drawing.Size(319, 323);
+      this.Size = new System.Drawing.Size(319, 347);
       ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).EndInit();
       this.commonGroupBox.ResumeLayout(false);
@@ -455,4 +476,6 @@
     private System.Windows.Forms.Label label5;
     private System.Windows.Forms.GroupBox axisGroupBox;
+    private System.Windows.Forms.TextBox displayNameTextBox;
+    private System.Windows.Forms.Label label9;
   }
 }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.cs	(revision 6647)
@@ -64,4 +64,5 @@
           binsApproximatelyRadioButton.Checked = false;
           binsExactRadioButton.Checked = false;
+          displayNameTextBox.Text = String.Empty;
         } else {
           chartTypeComboBox.SelectedItem = Content.ChartType;
@@ -83,4 +84,5 @@
           binsApproximatelyRadioButton.Checked = !Content.ExactBins;
           binsExactRadioButton.Checked = Content.ExactBins;
+          displayNameTextBox.Text = Content.DisplayName;
         }
       } finally { SuppressEvents = false; }
@@ -168,4 +170,13 @@
       }
     }
+
+    private void displayNameTextBox_Validated(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.DisplayName = displayNameTextBox.Text;
+        } finally { SuppressEvents = false; }
+      }
+    }
     #endregion
   }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.cs	(revision 6647)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using System.Windows.Forms;
 using HeuristicLab.Core.Views;
@@ -38,9 +39,19 @@
       using (DataTableVisualPropertiesDialog dialog = new DataTableVisualPropertiesDialog(current)) {
         if (dialog.ShowDialog() != DialogResult.OK) return;
+        Dictionary<string, bool> changeDisplayName = new Dictionary<string, bool>();
+        foreach (DataRow row in current.Rows) {
+          var answer = MessageBox.Show("Change display name for series " + row.Name + " to " + row.VisualProperties.DisplayName + " for all frames?", "Confirm change", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
+          if (answer == DialogResult.Cancel) return;
+          changeDisplayName[row.Name] = (answer == DialogResult.Yes);
+        }
         foreach (DataTable dt in Content) {
-          if (current != dt) {
-            dt.VisualProperties = (DataTableVisualProperties)current.VisualProperties.Clone();
-            foreach (DataRow row in current.Rows)
-              dt.Rows[row.Name].VisualProperties = (DataRowVisualProperties)row.VisualProperties.Clone();
+          if (current == dt) continue;
+          dt.VisualProperties = (DataTableVisualProperties)current.VisualProperties.Clone();
+          foreach (DataRow row in current.Rows) {
+            if (!dt.Rows.ContainsKey(row.Name)) continue;
+            string oldDisplayName = dt.Rows[row.Name].VisualProperties.DisplayName;
+            var props = (DataRowVisualProperties)row.VisualProperties.Clone();
+            if (!changeDisplayName[row.Name]) props.DisplayName = oldDisplayName;
+            dt.Rows[row.Name].VisualProperties = props;
           }
         }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 6647)
@@ -159,4 +159,6 @@
     protected virtual void AddDataRow(DataRow row) {
       Series series = new Series(row.Name);
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
       ConfigureSeries(series, row);
       FillSeriesWithRowValues(series, row);
@@ -212,5 +214,7 @@
       series.YAxisType = row.VisualProperties.SecondYAxis ? AxisType.Secondary : AxisType.Primary;
       series.XAxisType = row.VisualProperties.SecondXAxis ? AxisType.Secondary : AxisType.Primary;
-      series.ToolTip = row.Name + " X = #INDEX, Y = #VAL";
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
+      series.ToolTip = series.LegendText + " X = #INDEX, Y = #VAL";
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.Designer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.Designer.cs	(revision 6647)
@@ -69,5 +69,5 @@
       this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
       this.okButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-      this.okButton.Location = new System.Drawing.Point(307, 357);
+      this.okButton.Location = new System.Drawing.Point(307, 381);
       this.okButton.Name = "okButton";
       this.okButton.Size = new System.Drawing.Size(75, 23);
@@ -81,5 +81,5 @@
       this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
       this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
-      this.cancelButton.Location = new System.Drawing.Point(388, 357);
+      this.cancelButton.Location = new System.Drawing.Point(388, 381);
       this.cancelButton.Name = "cancelButton";
       this.cancelButton.Size = new System.Drawing.Size(75, 23);
@@ -99,5 +99,5 @@
       this.tabControl.Name = "tabControl";
       this.tabControl.SelectedIndex = 0;
-      this.tabControl.Size = new System.Drawing.Size(474, 350);
+      this.tabControl.Size = new System.Drawing.Size(474, 374);
       this.tabControl.TabIndex = 2;
       // 
@@ -108,5 +108,5 @@
       this.seriesTabPage.Name = "seriesTabPage";
       this.seriesTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.seriesTabPage.Size = new System.Drawing.Size(466, 324);
+      this.seriesTabPage.Size = new System.Drawing.Size(466, 348);
       this.seriesTabPage.TabIndex = 0;
       this.seriesTabPage.Text = "Series";
@@ -131,5 +131,5 @@
       this.splitContainer.Panel2.Controls.Add(this.dataRowVisualPropertiesControl);
       this.splitContainer.Panel2MinSize = 50;
-      this.splitContainer.Size = new System.Drawing.Size(460, 318);
+      this.splitContainer.Size = new System.Drawing.Size(460, 342);
       this.splitContainer.SplitterDistance = 125;
       this.splitContainer.TabIndex = 0;
@@ -165,5 +165,5 @@
       this.seriesListView.Name = "seriesListView";
       this.seriesListView.ShowGroups = false;
-      this.seriesListView.Size = new System.Drawing.Size(125, 289);
+      this.seriesListView.Size = new System.Drawing.Size(125, 313);
       this.seriesListView.TabIndex = 0;
       this.seriesListView.UseCompatibleStateImageBehavior = false;
@@ -177,5 +177,5 @@
       this.dataRowVisualPropertiesControl.Location = new System.Drawing.Point(0, 0);
       this.dataRowVisualPropertiesControl.Name = "dataRowVisualPropertiesControl";
-      this.dataRowVisualPropertiesControl.Size = new System.Drawing.Size(331, 318);
+      this.dataRowVisualPropertiesControl.Size = new System.Drawing.Size(331, 342);
       this.dataRowVisualPropertiesControl.TabIndex = 0;
       // 
@@ -206,5 +206,5 @@
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.CancelButton = this.cancelButton;
-      this.ClientSize = new System.Drawing.Size(475, 392);
+      this.ClientSize = new System.Drawing.Size(475, 416);
       this.Controls.Add(this.tabControl);
       this.Controls.Add(this.cancelButton);
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 6647)
@@ -83,15 +83,15 @@
     public DataRow(string name)
       : base(name) {
-      VisualProperties = new DataRowVisualProperties();
+      VisualProperties = new DataRowVisualProperties(name);
       values = new ObservableList<double>();
     }
     public DataRow(string name, string description)
       : base(name, description) {
-      VisualProperties = new DataRowVisualProperties();
+      VisualProperties = new DataRowVisualProperties(name);
       values = new ObservableList<double>();
     }
     public DataRow(string name, string description, IEnumerable<double> values)
       : base(name, description) {
-      VisualProperties = new DataRowVisualProperties();
+      VisualProperties = new DataRowVisualProperties(name);
       this.values = new ObservableList<double>(values);
     }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 6647)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.ComponentModel;
 using System.Drawing;
@@ -141,4 +142,19 @@
       }
     }
+    private string displayName;
+    public string DisplayName {
+      get { return displayName == null ? String.Empty : displayName; }
+      set {
+        if (displayName != value) {
+          if (value == null && displayName != String.Empty) {
+            displayName = String.Empty;
+            OnPropertyChanged("DisplayName");
+          } else if (value != null) {
+            displayName = value;
+            OnPropertyChanged("DisplayName");
+          }
+        }
+      }
+    }
 
     #region Persistence Properties
@@ -187,4 +203,9 @@
       get { return exactBins; }
       set { exactBins = value; }
+    }
+    [Storable(Name = "DisplayName")]
+    private string StorableDisplayName {
+      get { return displayName; }
+      set { displayName = value; }
     }
     #endregion
@@ -203,4 +224,5 @@
       this.bins = original.bins;
       this.exactBins = original.exactBins;
+      this.displayName = original.displayName;
     }
     public DataRowVisualProperties() {
@@ -214,4 +236,9 @@
       bins = 10;
       exactBins = false;
+      displayName = String.Empty;
+    }
+    public DataRowVisualProperties(string displayName)
+      : this() {
+      this.displayName = displayName;
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 6647)
@@ -139,4 +139,5 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="QualityAnalysis\QualityDistributionAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\ScaledQualityDifferenceAnalyzer.cs" />
     <Compile Include="ValueAnalysis\MinAverageMaxValueAnalyzer.cs" />
     <Compile Include="ValueAnalysis\MinAverageMaxValueCalculator.cs" />
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 6647)
@@ -126,5 +126,5 @@
           string appendix = " at " + iterationName + " " + iteration.Value.ToString();
           table.Name += appendix;
-          table.Rows["QualityDistribution"].Name += appendix;
+          table.Rows["QualityDistribution"].VisualProperties.DisplayName += appendix;
         }
         qdHistory.Add(table);
Index: /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 6647)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis.QualityAnalysis {
+  [Item("ScaledQualityDifferenceAnalyzer", @"Calculates the quality value relative to a certain range given with a minimum and a maximum value.
+The difference lies in the interval [0;1] if the range [min;max] is as large as the observed quality values, otherwise the difference will become < 0 or > 1.
+A value towards 0 always means that it's closer to the better fitness value, while a value towards 1 means that it's closer to the worse fitness value.")]
+  [StorableClass]
+  public class ScaledQualityDifferenceAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> ScaledDifferenceParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["ScaledDifference"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public IValueLookupParameter<DoubleValue> MinimumQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["MinimumQuality"]; }
+    }
+    public IValueLookupParameter<DoubleValue> MaximumQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["MaximumQuality"]; }
+    }
+
+    [StorableConstructor]
+    protected ScaledQualityDifferenceAnalyzer(bool deserializing) : base(deserializing) { }
+    protected ScaledQualityDifferenceAnalyzer(ScaledQualityDifferenceAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public ScaledQualityDifferenceAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value that should be compared."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise."));
+      Parameters.Add(new LookupParameter<DoubleValue>("ScaledDifference", "The value that describes whether the quality value lies towards the better quality in the range (<=0.5) or more towards the worse quality (> 0.5)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection where the difference will be stored (in addition to the scope)."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MinimumQuality", "The lower bound of the quality range to which the quality is compared."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaximumQuality", "The upper bound of the quality range to which the quality is compared."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScaledQualityDifferenceAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double quality = QualityParameter.ActualValue.Value, max = MaximumQualityParameter.ActualValue.Value, min = MinimumQualityParameter.ActualValue.Value;
+      double difference;
+
+      difference = ((quality - min) / (max - min));
+      if (maximization) difference = 1.0 - difference;
+
+      DoubleValue differenceValue = ScaledDifferenceParameter.ActualValue;
+      if (differenceValue == null) {
+        differenceValue = new DoubleValue(difference);
+        ScaledDifferenceParameter.ActualValue = differenceValue;
+      } else differenceValue.Value = difference;
+
+      ResultCollection results = ResultsParameter.ActualValue;
+      if (results != null) {
+        IResult r;
+        if (!results.TryGetValue(ScaledDifferenceParameter.ActualName, out r)) {
+          r = new Result(ScaledDifferenceParameter.ActualName, differenceValue);
+          results.Add(r);
+        }
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Data.Views/3.3/StringConvertibleArrayView.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Data.Views/3.3/StringConvertibleArrayView.Designer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Data.Views/3.3/StringConvertibleArrayView.Designer.cs	(revision 6647)
@@ -116,8 +116,8 @@
     #endregion
 
-    private System.Windows.Forms.Label lengthLabel;
-    private System.Windows.Forms.TextBox lengthTextBox;
-    private System.Windows.Forms.DataGridView dataGridView;
-    private System.Windows.Forms.ErrorProvider errorProvider;
+    protected System.Windows.Forms.DataGridView dataGridView;
+    protected System.Windows.Forms.Label lengthLabel;
+    protected System.Windows.Forms.TextBox lengthTextBox;
+    protected System.Windows.Forms.ErrorProvider errorProvider;
 
   }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/HeuristicLab.Encodings.PermutationEncoding.Views-3.3.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/HeuristicLab.Encodings.PermutationEncoding.Views-3.3.csproj	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/HeuristicLab.Encodings.PermutationEncoding.Views-3.3.csproj	(revision 6647)
@@ -12,5 +12,6 @@
     <AssemblyName>HeuristicLab.Encodings.PermutationEncoding.Views-3.3</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
     <SignAssembly>true</SignAssembly>
@@ -92,4 +93,8 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
+    <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
     <Reference Include="System" />
     <Reference Include="System.Core">
@@ -98,4 +103,5 @@
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
     <Reference Include="System.Xml.Linq">
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -115,4 +121,10 @@
     </Compile>
     <Compile Include="HeuristicLabEncodingsPermutationEncodingViewsPlugin.cs" />
+    <Compile Include="PermutationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PermutationView.Designer.cs">
+      <DependentUpon>PermutationView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
@@ -135,4 +147,8 @@
       <Name>HeuristicLab.Core-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data.Views\3.3\HeuristicLab.Data.Views-3.3.csproj">
+      <Project>{72104A0B-90E7-42F3-9ABE-9BBBADD4B943}</Project>
+      <Name>HeuristicLab.Data.Views-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
@@ -150,4 +166,8 @@
       <Project>{3BD61258-31DA-4B09-89C0-4F71FEF5F05A}</Project>
       <Name>HeuristicLab.MainForm-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj">
+      <Project>{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}</Project>
+      <Name>HeuristicLab.Optimization.Views-3.3</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/HeuristicLabEncodingsPermutationEncodingViewsPlugin.cs.frame
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/HeuristicLabEncodingsPermutationEncodingViewsPlugin.cs.frame	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/HeuristicLabEncodingsPermutationEncodingViewsPlugin.cs.frame	(revision 6647)
@@ -31,4 +31,5 @@
   [PluginDependency("HeuristicLab.Core.Views", "3.3")]
   [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Data.Views", "3.3")]
   [PluginDependency("HeuristicLab.Encodings.PermutationEncoding", "3.3")]
   [PluginDependency("HeuristicLab.MainForm", "3.3")]
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/PermutationView.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/PermutationView.Designer.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/PermutationView.Designer.cs	(revision 6647)
@@ -0,0 +1,88 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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
+
+namespace HeuristicLab.Encodings.PermutationEncoding.Views {
+  partial class PermutationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.permutationTypeView = new HeuristicLab.Encodings.PermutationEncoding.Views.PermutationTypeView();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // lengthTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.lengthTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.lengthTextBox, 2);
+      // 
+      // permutationTypeView
+      // 
+      this.permutationTypeView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.permutationTypeView.Caption = "PermutationType View";
+      this.permutationTypeView.Content = null;
+      this.permutationTypeView.Location = new System.Drawing.Point(6, 26);
+      this.permutationTypeView.Name = "permutationTypeView";
+      this.permutationTypeView.ReadOnly = false;
+      this.permutationTypeView.Size = new System.Drawing.Size(418, 29);
+      this.permutationTypeView.TabIndex = 3;
+      // 
+      // PermutationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.permutationTypeView);
+      this.Name = "PermutationView";
+      this.Controls.SetChildIndex(this.permutationTypeView, 0);
+      this.Controls.SetChildIndex(this.lengthLabel, 0);
+      this.Controls.SetChildIndex(this.lengthTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private PermutationTypeView permutationTypeView;
+
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/PermutationView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/PermutationView.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding.Views/3.3/PermutationView.cs	(revision 6647)
@@ -0,0 +1,81 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Windows.Forms;
+using HeuristicLab.Data.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Encodings.PermutationEncoding.Views {
+  [View("Permutation View")]
+  [Content(typeof(Permutation), IsDefaultView = true)]
+  public partial class PermutationView : StringConvertibleArrayView {
+    public new Permutation Content {
+      get { return (Permutation)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public PermutationView() {
+      InitializeComponent();
+      dataGridView.Top = permutationTypeView.Bottom + permutationTypeView.Margin.Bottom + dataGridView.Margin.Top;
+    }
+
+    #region Register Content Events
+    protected override void DeregisterContentEvents() {
+      Content.PermutationTypeChanged -= new System.EventHandler(Content_PermutationTypeChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.PermutationTypeChanged += new System.EventHandler(Content_PermutationTypeChanged);
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        if (permutationTypeView.Content != null)
+          permutationTypeView.Content.ValueChanged -= new System.EventHandler(PermutationTypeView_ValueChanged);
+        permutationTypeView.Content = null;
+      } else {
+        permutationTypeView.Content = new PermutationType(Content.PermutationType);
+        permutationTypeView.Content.ValueChanged += new System.EventHandler(PermutationTypeView_ValueChanged);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+    }
+
+    #region Event Handlers
+
+    private void Content_PermutationTypeChanged(object sender, System.EventArgs e) {
+      if (permutationTypeView.Content.Value != Content.PermutationType)
+        permutationTypeView.Content.Value = Content.PermutationType;
+    }
+
+    private void PermutationTypeView_ValueChanged(object sender, System.EventArgs e) {
+      if (permutationTypeView.Content.Value != Content.PermutationType)
+        Content.PermutationType = permutationTypeView.Content.Value;
+    }
+    #endregion
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs	(revision 6647)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -36,4 +37,9 @@
     public PermutationTypes PermutationType {
       get { return permutationType; }
+      set {
+        bool changed = (permutationType != value);
+        permutationType = value;
+        if (changed) OnPermutationTypeChanged();
+      }
     }
 
@@ -45,5 +51,6 @@
     }
     public Permutation() : this(PermutationTypes.RelativeUndirected) { }
-    public Permutation(PermutationTypes type) : base() {
+    public Permutation(PermutationTypes type)
+      : base() {
       permutationType = type;
     }
@@ -58,8 +65,10 @@
       Randomize(random);
     }
-    public Permutation(PermutationTypes type, int[] elements) : base(elements) {
+    public Permutation(PermutationTypes type, int[] elements)
+      : base(elements) {
       permutationType = type;
     }
-    public Permutation(PermutationTypes type, IntArray elements) : this(type, elements.Length) {
+    public Permutation(PermutationTypes type, IntArray elements)
+      : this(type, elements.Length) {
       for (int i = 0; i < array.Length; i++)
         array[i] = elements[i];
@@ -111,4 +120,11 @@
       return this[position];
     }
+
+    public event EventHandler PermutationTypeChanged;
+
+    protected virtual void OnPermutationTypeChanged() {
+      var handler = PermutationTypeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
   }
 }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.RealVectorEncoding/3.3/Manipulators/BreederGeneticAlgorithmManipulator.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.RealVectorEncoding/3.3/Manipulators/BreederGeneticAlgorithmManipulator.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.RealVectorEncoding/3.3/Manipulators/BreederGeneticAlgorithmManipulator.cs	(revision 6647)
@@ -52,5 +52,6 @@
     public BreederGeneticAlgorithmManipulator()
       : base() {
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("SearchIntervalFactor", "The factor determining the size of the search interval, that will be added/removed to/from the allele selected for manipulation. E.g. a value of 0.1 means 10% of the range will be maximally added/removed.", new DoubleValue(0.1)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("SearchIntervalFactor", @"Scales the manipulation strength as a factor of the range. The range is determined by the bounds interval.
+A value of 0.1 means that certain components of the vector are moved by values in the non-uniform interval [0;0.1*range].", new DoubleValue(0.1)));
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 6647)
@@ -576,5 +576,5 @@
     private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
       if (rightClickOccured) return;
-      if (e.X < e.Node.Bounds.Left || e.X > e.Node.Bounds.Right) return;
+      if (e.X < e.Node.Bounds.Left - treeView.ImageList.Images[e.Node.ImageIndex].Width || e.X > e.Node.Bounds.Right) return;
       e.Node.Toggle();
       IContent optimizer = (IContent)e.Node.Tag;
@@ -582,5 +582,5 @@
     }
     private void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
-      if (e.X < e.Node.Bounds.Left || e.X > e.Node.Bounds.Right) return;
+      if (e.X < e.Node.Bounds.Left - treeView.ImageList.Images[e.Node.ImageIndex].Width || e.X > e.Node.Bounds.Right) return;
       treeView.SelectedNode = e.Node;
       detailsViewHost.Content = (IContent)e.Node.Tag;
@@ -593,5 +593,5 @@
       Point coordinates = new Point(e.X, e.Y);
       TreeNode node = treeView.GetNodeAt(coordinates);
-      if (node == null || coordinates.X < node.Bounds.Left || coordinates.X > node.Bounds.Right) {
+      if (node == null || coordinates.X < node.Bounds.Left - treeView.ImageList.Images[node.ImageIndex].Width || coordinates.X > node.Bounds.Right) {
         treeView.SelectedNode = null;
         detailsViewHost.Content = null;
@@ -723,6 +723,5 @@
             algorithm.Problem = problem;
           }
-        }
-        catch (Exception ex) {
+        } catch (Exception ex) {
           ErrorHandling.ShowErrorDialog(this, ex);
         }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Optimization.Views/3.3/RunCollectionBoxPlotView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Optimization.Views/3.3/RunCollectionBoxPlotView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Optimization.Views/3.3/RunCollectionBoxPlotView.cs	(revision 6647)
@@ -53,4 +53,7 @@
       chart.ChartAreas.Add(BoxPlotChartAreaName);
       chart.CustomizeAllChartAreas();
+      chart.ChartAreas[BoxPlotChartAreaName].Axes.ToList().ForEach(x => { x.ScaleView.Zoomable = true; x.ScaleView.MinSize = 0; });
+      chart.ChartAreas[BoxPlotChartAreaName].CursorX.Interval = 0.5;
+      chart.ChartAreas[BoxPlotChartAreaName].CursorY.Interval = 1e-5;
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Optimization/3.3/Result.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Optimization/3.3/Result.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Optimization/3.3/Result.cs	(revision 6647)
@@ -39,4 +39,11 @@
         if (value != null) return value.ItemImage;
         else return base.ItemImage;
+      }
+    }
+
+    public override string ItemDescription {
+      get {
+        if (Description != String.Empty) return Description;
+        else return base.ItemDescription;
       }
     }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views-3.4.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views-3.4.csproj	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views-3.4.csproj	(revision 6647)
@@ -117,4 +117,10 @@
       <DependentUpon>InteractiveSymbolicRegressionSolutionSimplifierView.cs</DependentUpon>
     </Compile>
+    <Compile Include="SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="SymbolicRegressionSolutionErrorCharacteristicsCurveView.Designer.cs">
+      <DependentUpon>SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
+    </Compile>
     <Compile Include="SymbolicRegressionSolutionView.cs">
       <SubType>UserControl</SubType>
@@ -129,4 +135,8 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Algorithms.DataAnalysis\3.4\HeuristicLab.Algorithms.DataAnalysis-3.4.csproj">
+      <Project>{2E782078-FA81-4B70-B56F-74CE38DAC6C8}</Project>
+      <Name>HeuristicLab.Algorithms.DataAnalysis-3.4</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
       <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
@@ -208,4 +218,8 @@
       <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
       <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Visualization.ChartControlsExtensions\3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj">
+      <Project>{315BDA09-3F4F-49B3-9790-B37CFC1C5750}</Project>
+      <Name>HeuristicLab.Visualization.ChartControlsExtensions-3.3</Name>
     </ProjectReference>
   </ItemGroup>
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/HeuristicLabProblemsDataAnalysisSymbolicRegressionViewsPlugin.cs.frame
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/HeuristicLabProblemsDataAnalysisSymbolicRegressionViewsPlugin.cs.frame	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/HeuristicLabProblemsDataAnalysisSymbolicRegressionViewsPlugin.cs.frame	(revision 6647)
@@ -28,4 +28,6 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views", "Provides views for symbolic regression problem classes.", "3.4.1.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views-3.4.dll",PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Algorithms.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
   [PluginDependency("HeuristicLab.Core", "3.3")]
@@ -41,4 +43,5 @@
   [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Views", "3.4")]
   [PluginDependency("HeuristicLab.Problems.DataAnalysis.Views", "3.4")]
+  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
   public class HeuristicLabProblemsDataAnalysisSymbolicRegressionViewsPlugin : PluginBase {
   }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 6647)
@@ -0,0 +1,46 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views {
+  partial class SymbolicRegressionSolutionErrorCharacteristicsCurveView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      // 
+      // SymbolicRegressionSolutionErrorCharacteristicsCurveView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "SymbolicRegressionSolutionErrorCharacteristicsCurveView";
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs	(revision 6647)
@@ -0,0 +1,102 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Algorithms.DataAnalysis;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views {
+  [View("Error Characteristics Curve")]
+  [Content(typeof(ISymbolicRegressionSolution))]
+  public partial class SymbolicRegressionSolutionErrorCharacteristicsCurveView : RegressionSolutionErrorCharacteristicsCurveView {
+    private IRegressionSolution linearRegressionSolution;
+    public SymbolicRegressionSolutionErrorCharacteristicsCurveView() {
+      InitializeComponent();
+    }
+
+    public new ISymbolicRegressionSolution Content {
+      get { return (ISymbolicRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      if (Content != null)
+        linearRegressionSolution = CreateLinearRegressionSolution();
+      else
+        linearRegressionSolution = null;
+
+      base.OnContentChanged();
+    }
+
+    protected override void UpdateChart() {
+      base.UpdateChart();
+      if (Content == null || linearRegressionSolution == null) return;
+      AddRegressionSolution(linearRegressionSolution);
+    }
+
+    private IRegressionSolution CreateLinearRegressionSolution() {
+      if (Content == null) throw new InvalidOperationException();
+      double rmse, cvRmsError;
+      var problemData = (IRegressionProblemData)ProblemData.Clone();
+
+      //clear checked inputVariables
+      foreach (var inputVariable in problemData.InputVariables.CheckedItems) {
+        problemData.InputVariables.SetItemCheckedState(inputVariable.Value, false);
+      }
+
+      //check inputVariables used in the symbolic regression model
+      var usedVariables =
+        Content.Model.SymbolicExpressionTree.IterateNodesPostfix().OfType<VariableTreeNode>().Select(
+          node => node.VariableName).Distinct();
+      foreach (var variable in usedVariables) {
+        problemData.InputVariables.SetItemCheckedState(
+          problemData.InputVariables.Where(x => x.Value == variable).First(), true);
+      }
+
+      var solution = LinearRegression.CreateLinearRegressionSolution(problemData, out rmse, out cvRmsError);
+      solution.Name = "Linear Model";
+      return solution;
+    }
+
+    protected override void Content_ModelChanged(object sender, EventArgs e) {
+      linearRegressionSolution = CreateLinearRegressionSolution();
+      base.Content_ModelChanged(sender, e);
+    }
+
+    protected override void Content_ProblemDataChanged(object sender, EventArgs e) {
+      linearRegressionSolution = CreateLinearRegressionSolution();
+      base.Content_ProblemDataChanged(sender, e);
+    }
+
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      if (e.Clicks < 2) return;
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType != ChartElementType.LegendItem) return;
+      if (result.Series.Name != linearRegressionSolution.Name) return;
+
+      MainFormManager.MainForm.ShowContent((IRegressionSolution)result.Series.Tag);
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs	(revision 6647)
@@ -19,46 +19,47 @@
  */
 #endregion
-
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
-  #region License Information
-  /* HeuristicLab
- * Copyright (C) 2002-2011 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.Windows.Forms;
-  using HeuristicLab.Core;
-  using HeuristicLab.Core.Views;
-  using HeuristicLab.MainForm;
-  using HeuristicLab.MainForm.WindowsForms;
+  [View("Ensemble Solutions")]
+  [Content(typeof(ClassificationEnsembleSolution), false)]
+  internal sealed partial class ClassificationEnsembleSolutionModelView : DataAnalysisSolutionEvaluationView {
+    private ModelsView view;
 
-  [View("Ensemble Solutions")]
-  [Content(typeof(IItemCollection<IClassificationSolution>), false)]
-  internal sealed partial class ClassificationEnsembleSolutionModelView : ItemCollectionView<IClassificationSolution> {
     public ClassificationEnsembleSolutionModelView() {
       InitializeComponent();
+      view = new ModelsView();
+      view.Dock = DockStyle.Fill;
+      Controls.Add(view);
     }
 
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
-      removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
-      itemsListView.Enabled = Content != null;
-      detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+    public new ClassificationEnsembleSolution Content {
+      get { return (ClassificationEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null)
+        view.Content = Content.ClassificationSolutions;
+      else
+        view.Content = null;
+    }
+
+    public override System.Drawing.Image ViewImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Properties; }
+    }
+
+    private class ModelsView : ItemCollectionView<IClassificationSolution> {
+      protected override void SetEnabledStateOfControls() {
+        base.SetEnabledStateOfControls();
+        addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
+        removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
+        itemsListView.Enabled = Content != null;
+        detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+      }
     }
   }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs	(revision 6647)
@@ -24,5 +24,4 @@
 using System.Linq;
 using System.Windows.Forms;
-using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -31,5 +30,5 @@
   [View("Confusion Matrix")]
   [Content(typeof(IClassificationSolution))]
-  public partial class ClassificationSolutionConfusionMatrixView : ItemView, IClassificationSolutionEvaluationView {
+  public partial class ClassificationSolutionConfusionMatrixView : DataAnalysisSolutionEvaluationView {
     private const string TrainingSamples = "Training";
     private const string TestSamples = "Test";
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs	(revision 6647)
@@ -22,5 +22,4 @@
 using System.Linq;
 using System.Windows.Forms;
-using HeuristicLab.Core.Views;
 using HeuristicLab.Data;
 using HeuristicLab.Data.Views;
@@ -31,5 +30,5 @@
   [View("Estimated Class Values")]
   [Content(typeof(IClassificationSolution))]
-  public partial class ClassificationSolutionEstimatedClassValuesView : ItemView, IClassificationSolutionEvaluationView {
+  public partial class ClassificationSolutionEstimatedClassValuesView : DataAnalysisSolutionEvaluationView {
     private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
     private const string ESTIMATEDVALUES_SERIES_NAME = "Estimated Class Values (all)";
@@ -39,10 +38,8 @@
     public new IClassificationSolution Content {
       get { return (IClassificationSolution)base.Content; }
-      set {
-        base.Content = value;
-      }
+      set { base.Content = value; }
     }
 
-    private StringConvertibleMatrixView matrixView;
+    protected StringConvertibleMatrixView matrixView;
 
     public ClassificationSolutionEstimatedClassValuesView()
@@ -82,5 +79,5 @@
     }
 
-    private void UpdateEstimatedValues() {
+    protected virtual void UpdateEstimatedValues() {
       if (InvokeRequired) Invoke((Action)UpdateEstimatedValues);
       else {
@@ -111,5 +108,5 @@
 
           matrix = new StringMatrix(values);
-          matrix.ColumnNames = new string[] {"Id", TARGETVARIABLE_SERIES_NAME, ESTIMATEDVALUES_SERIES_NAME, ESTIMATEDVALUES_TRAINING_SERIES_NAME, ESTIMATEDVALUES_TEST_SERIES_NAME };
+          matrix.ColumnNames = new string[] { "Id", TARGETVARIABLE_SERIES_NAME, ESTIMATEDVALUES_SERIES_NAME, ESTIMATEDVALUES_TRAINING_SERIES_NAME, ESTIMATEDVALUES_TEST_SERIES_NAME };
           matrix.SortableView = true;
         }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 6647)
@@ -28,5 +28,4 @@
 using System.Windows.Forms.DataVisualization.Charting;
 using HeuristicLab.Common;
-using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -34,5 +33,5 @@
   [View("ROC Curves")]
   [Content(typeof(IDiscriminantFunctionClassificationSolution))]
-  public partial class DiscriminantFunctionClassificationRocCurvesView : ItemView, IDiscriminantFunctionClassificationSolutionEvaluationView {
+  public partial class DiscriminantFunctionClassificationRocCurvesView : DataAnalysisSolutionEvaluationView {
     private const string xAxisTitle = "False Positive Rate";
     private const string yAxisTitle = "True Positive Rate";
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs	(revision 6647)
@@ -22,7 +22,5 @@
 using System.Linq;
 using System.Windows.Forms;
-using HeuristicLab.Core.Views;
 using HeuristicLab.Data;
-using HeuristicLab.Data.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -31,5 +29,5 @@
   [View("Estimated Class Values")]
   [Content(typeof(IDiscriminantFunctionClassificationSolution))]
-  public partial class DiscriminantFunctionClassificationSolutionEstimatedClassValuesView : ItemView, IDiscriminantFunctionClassificationSolutionEvaluationView {
+  public partial class DiscriminantFunctionClassificationSolutionEstimatedClassValuesView : ClassificationSolutionEstimatedClassValuesView {
     private const string TargetClassValuesSeriesname = "TargetVariable";
     private const string EstimatedClassValuesSeriesName = "EstimatedClassValues";
@@ -38,48 +36,13 @@
     public new IDiscriminantFunctionClassificationSolution Content {
       get { return (IDiscriminantFunctionClassificationSolution)base.Content; }
-      set {
-        base.Content = value;
-      }
+      set { base.Content = value; }
     }
-
-    private StringConvertibleMatrixView matrixView;
 
     public DiscriminantFunctionClassificationSolutionEstimatedClassValuesView()
       : base() {
       InitializeComponent();
-      matrixView = new StringConvertibleMatrixView();
-      matrixView.ShowRowsAndColumnsTextBox = false;
-      matrixView.ShowStatisticalInformation = false;
-      matrixView.Dock = DockStyle.Fill;
-      this.Controls.Add(matrixView);
     }
 
-    #region events
-    protected override void RegisterContentEvents() {
-      base.RegisterContentEvents();
-      Content.ModelChanged += new EventHandler(Content_ModelChanged);
-      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
-    }
-
-    protected override void DeregisterContentEvents() {
-      base.DeregisterContentEvents();
-      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
-      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
-    }
-
-    private void Content_ProblemDataChanged(object sender, EventArgs e) {
-      OnContentChanged();
-    }
-
-    private void Content_ModelChanged(object sender, EventArgs e) {
-      OnContentChanged();
-    }
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      UpdateEstimatedValues();
-    }
-
-    private void UpdateEstimatedValues() {
+    protected override void UpdateEstimatedValues() {
       if (InvokeRequired) Invoke((Action)UpdateEstimatedValues);
       else {
@@ -105,5 +68,4 @@
       }
     }
-    #endregion
   }
 }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 6647)
@@ -27,5 +27,4 @@
 using System.Windows.Forms.DataVisualization.Charting;
 using HeuristicLab.Common;
-using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -34,5 +33,5 @@
   [View("Classification Threshold")]
   [Content(typeof(IDiscriminantFunctionClassificationSolution), true)]
-  public sealed partial class DiscriminantFunctionClassificationSolutionThresholdView : ItemView, IDiscriminantFunctionClassificationSolutionEvaluationView {
+  public sealed partial class DiscriminantFunctionClassificationSolutionThresholdView : DataAnalysisSolutionEvaluationView {
     private const double TrainingAxisValue = 0.0;
     private const double TestAxisValue = 10.0;
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs	(revision 6647)
@@ -22,5 +22,4 @@
 using System.Linq;
 using System.Windows.Forms;
-using HeuristicLab.Core.Views;
 using HeuristicLab.Data;
 using HeuristicLab.Data.Views;
@@ -31,5 +30,5 @@
   [View("Estimated Clusters")]
   [Content(typeof(IClusteringSolution))]
-  public partial class ClusteringSolutionEstimatedClusterView : ItemView, IClusteringSolutionEvaluationView {
+  public partial class ClusteringSolutionEstimatedClusterView : DataAnalysisSolutionEvaluationView {
     private const string CLUSTER_NAMES = "Cluster";
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs	(revision 6647)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DataAnalysisSolutionEvaluationView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs	(revision 6647)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Drawing;
+using HeuristicLab.Core.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class DataAnalysisSolutionEvaluationView : ItemView, IDataAnalysisSolutionEvaluationView {
+    public DataAnalysisSolutionEvaluationView() {
+      InitializeComponent();
+    }
+
+    public new IDataAnalysisSolution Content {
+      get { return (IDataAnalysisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public virtual Image ViewImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Graph; }
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 6647)
@@ -116,4 +116,16 @@
       <DependentUpon>ClassificationEnsembleSolutionModelView.cs</DependentUpon>
     </Compile>
+    <Compile Include="DataAnalysisSolutionEvaluationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataAnalysisSolutionEvaluationView.Designer.cs">
+      <DependentUpon>DataAnalysisSolutionEvaluationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionErrorCharacteristicsCurveView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionErrorCharacteristicsCurveView.Designer.cs">
+      <DependentUpon>RegressionSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Regression\RegressionEnsembleSolutionModelView.cs">
       <SubType>UserControl</SubType>
@@ -170,10 +182,4 @@
       <DependentUpon>ClusteringSolutionView.cs</DependentUpon>
     </Compile>
-    <Compile Include="Solution Views\ClassificationEnsembleSolutionView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="Solution Views\ClassificationEnsembleSolutionView.Designer.cs">
-      <DependentUpon>ClassificationEnsembleSolutionView.cs</DependentUpon>
-    </Compile>
     <Compile Include="Solution Views\DiscriminantFunctionClassificationSolutionView.cs">
       <SubType>UserControl</SubType>
@@ -182,7 +188,4 @@
       <DependentUpon>DiscriminantFunctionClassificationSolutionView.cs</DependentUpon>
     </Compile>
-    <Compile Include="Interfaces\IDiscriminantFunctionClassificationSolutionEvaluationView.cs" />
-    <Compile Include="Interfaces\IClusteringSolutionEvaluationView.cs" />
-    <Compile Include="Interfaces\IClassificationSolutionEvaluationView.cs" />
     <Compile Include="Solution Views\DataAnalysisSolutionView.cs">
       <SubType>UserControl</SubType>
@@ -197,12 +200,6 @@
       <DependentUpon>DoubleLimitView.cs</DependentUpon>
     </Compile>
-    <Compile Include="Interfaces\IRegressionSolutionEvaluationView.cs" />
+    <Compile Include="Interfaces\IDataAnalysisSolutionEvaluationView.cs" />
     <Compile Include="MenuItems\CreateEnsembleMenuItem.cs" />
-    <Compile Include="Solution Views\RegressionEnsembleSolutionView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="Solution Views\RegressionEnsembleSolutionView.Designer.cs">
-      <DependentUpon>RegressionEnsembleSolutionView.cs</DependentUpon>
-    </Compile>
     <Compile Include="Solution Views\RegressionSolutionView.cs">
       <SubType>UserControl</SubType>
@@ -336,5 +333,4 @@
     </BootstrapperPackage>
   </ItemGroup>
-  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs	(revision 6647)
@@ -21,7 +21,9 @@
 
 
+using System.Drawing;
 using HeuristicLab.MainForm;
 namespace HeuristicLab.Problems.DataAnalysis.Views {
-  public interface IDataAnalysisSolutionEvaluationView : IContentView {
+  public interface IDataAnalysisSolutionEvaluationView :IContentView {
+    Image ViewImage { get; }
   }
 }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 6647)
@@ -19,46 +19,47 @@
  */
 #endregion
-
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
-  #region License Information
-  /* HeuristicLab
- * Copyright (C) 2002-2011 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.Windows.Forms;
-  using HeuristicLab.Core;
-  using HeuristicLab.Core.Views;
-  using HeuristicLab.MainForm;
-  using HeuristicLab.MainForm.WindowsForms;
+  [View("Ensemble Solutions")]
+  [Content(typeof(RegressionEnsembleSolution), false)]
+  internal sealed partial class RegressionEnsembleSolutionModelView : DataAnalysisSolutionEvaluationView {
+    private ModelsView view;
 
-  [View("Ensemble Solutions")]
-  [Content(typeof(IItemCollection<IRegressionSolution>), false)]
-  internal sealed partial class RegressionEnsembleSolutionModelView : ItemCollectionView<IRegressionSolution> {
     public RegressionEnsembleSolutionModelView() {
       InitializeComponent();
+      view = new ModelsView();
+      view.Dock = DockStyle.Fill;
+      Controls.Add(view);
     }
 
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
-      removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
-      itemsListView.Enabled = Content != null;
-      detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+    public new RegressionEnsembleSolution Content {
+      get { return (RegressionEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null)
+        view.Content = Content.RegressionSolutions;
+      else
+        view.Content = null;
+    }
+
+    public override System.Drawing.Image ViewImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Properties; }
+    }
+
+    private class ModelsView : ItemCollectionView<IRegressionSolution> {
+      protected override void SetEnabledStateOfControls() {
+        base.SetEnabledStateOfControls();
+        addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
+        removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
+        itemsListView.Enabled = Content != null;
+        detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+      }
     }
   }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 6647)
@@ -0,0 +1,92 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionErrorCharacteristicsCurveView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.label1 = new System.Windows.Forms.Label();
+      this.cmbSamples = new System.Windows.Forms.ComboBox();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.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)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Legend1";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(6, 28);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(366, 202);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "chart";
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 6);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(47, 13);
+      this.label1.TabIndex = 4;
+      this.label1.Text = "Samples";
+      // 
+      // cmbSamples
+      // 
+      this.cmbSamples.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbSamples.FormattingEnabled = true;
+      this.cmbSamples.Location = new System.Drawing.Point(56, 3);
+      this.cmbSamples.Name = "cmbSamples";
+      this.cmbSamples.Size = new System.Drawing.Size(121, 21);
+      this.cmbSamples.TabIndex = 3;
+      this.cmbSamples.SelectedIndexChanged += new System.EventHandler(this.cmbSamples_SelectedIndexChanged);
+      // 
+      // RegressionSolutionErrorCharacteristicsCurveView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.cmbSamples);
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionErrorCharacteristicsCurveView";
+      this.Size = new System.Drawing.Size(366, 230);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    protected System.Windows.Forms.Label label1;
+    protected System.Windows.Forms.ComboBox cmbSamples;
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 6647)
@@ -0,0 +1,227 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Error Characteristics Curve")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionErrorCharacteristicsCurveView : DataAnalysisSolutionEvaluationView {
+    protected const string TrainingSamples = "Training";
+    protected const string TestSamples = "Test";
+    protected const string AllSamples = "All Samples";
+
+    public RegressionSolutionErrorCharacteristicsCurveView()
+      : base() {
+      InitializeComponent();
+
+      cmbSamples.Items.Add(TrainingSamples);
+      cmbSamples.Items.Add(TestSamples);
+      cmbSamples.Items.Add(AllSamples);
+
+      cmbSamples.SelectedIndex = 0;
+
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].AxisX.Title = "Absolute Error";
+      chart.ChartAreas[0].AxisX.Minimum = 0.0;
+      chart.ChartAreas[0].AxisX.Maximum = 1.0;
+      chart.ChartAreas[0].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
+      chart.ChartAreas[0].CursorX.Interval = 0.01;
+
+      chart.ChartAreas[0].AxisY.Title = "Number of Samples";
+      chart.ChartAreas[0].AxisY.Minimum = 0.0;
+      chart.ChartAreas[0].AxisY.Maximum = 1.0;
+      chart.ChartAreas[0].AxisY.MajorGrid.Interval = 0.2;
+      chart.ChartAreas[0].CursorY.Interval = 0.01;
+    }
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+    public IRegressionProblemData ProblemData {
+      get {
+        if (Content == null) return null;
+        return Content.ProblemData;
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected virtual void Content_ModelChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_ModelChanged, sender, e);
+      else UpdateChart();
+    }
+    protected virtual void Content_ProblemDataChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_ProblemDataChanged, sender, e);
+      else {
+        UpdateChart();
+      }
+    }
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateChart();
+    }
+
+    protected virtual void UpdateChart() {
+      chart.Series.Clear();
+      chart.Annotations.Clear();
+      if (Content == null) return;
+
+      var originalValues = GetOriginalValues();
+      var meanModelEstimatedValues = GetMeanModelEstimatedValues(originalValues);
+      var meanModelResiduals = GetResiduals(originalValues, meanModelEstimatedValues);
+
+      meanModelResiduals.Sort();
+      chart.ChartAreas[0].AxisX.Maximum = Math.Ceiling(meanModelResiduals.Last());
+      chart.ChartAreas[0].CursorX.Interval = meanModelResiduals.First() / 100;
+
+      Series meanModelSeries = new Series("Mean Model");
+      meanModelSeries.ChartType = SeriesChartType.FastLine;
+      UpdateSeries(meanModelResiduals, meanModelSeries);
+      meanModelSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(meanModelSeries);
+      chart.Series.Add(meanModelSeries);
+
+      AddRegressionSolution(Content);
+    }
+
+    protected void AddRegressionSolution(IRegressionSolution solution) {
+      if (chart.Series.Any(s => s.Name == solution.Name)) return;
+
+      Series solutionSeries = new Series(solution.Name);
+      solutionSeries.Tag = solution;
+      solutionSeries.ChartType = SeriesChartType.FastLine;
+      var estimatedValues = GetResiduals(GetOriginalValues(), GetEstimatedValues(solution));
+      UpdateSeries(estimatedValues, solutionSeries);
+      solutionSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(solutionSeries);
+      chart.Series.Add(solutionSeries);
+    }
+
+    protected void UpdateSeries(List<double> residuals, Series series) {
+      series.Points.Clear();
+      residuals.Sort();
+
+      series.Points.AddXY(0, 0);
+      for (int i = 0; i < residuals.Count; i++) {
+        var point = new DataPoint();
+        if (residuals[i] > chart.ChartAreas[0].AxisX.Maximum) {
+          point.XValue = chart.ChartAreas[0].AxisX.Maximum;
+          point.YValues[0] = ((double)i - 1) / residuals.Count;
+          point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+          series.Points.Add(point);
+          break;
+        }
+
+        point.XValue = residuals[i];
+        point.YValues[0] = ((double)i) / residuals.Count;
+        point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+        series.Points.Add(point);
+      }
+
+      if (series.Points.Last().XValue < chart.ChartAreas[0].AxisX.Maximum) {
+        var point = new DataPoint();
+        point.XValue = chart.ChartAreas[0].AxisX.Maximum;
+        point.YValues[0] = 1;
+        point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+        series.Points.Add(point);
+      }
+    }
+
+    protected IEnumerable<double> GetOriginalValues() {
+      IEnumerable<double> originalValues;
+      switch (cmbSamples.SelectedItem.ToString()) {
+        case TrainingSamples:
+          originalValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+          break;
+        case TestSamples:
+          originalValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
+          break;
+        case AllSamples:
+          originalValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable);
+          break;
+        default:
+          throw new NotSupportedException();
+      }
+      return originalValues;
+    }
+
+    protected IEnumerable<double> GetEstimatedValues(IRegressionSolution solution) {
+      IEnumerable<double> estimatedValues;
+      switch (cmbSamples.SelectedItem.ToString()) {
+        case TrainingSamples:
+          estimatedValues = solution.EstimatedTrainingValues;
+          break;
+        case TestSamples:
+          estimatedValues = solution.EstimatedTestValues;
+          break;
+        case AllSamples:
+          estimatedValues = solution.EstimatedValues;
+          break;
+        default:
+          throw new NotSupportedException();
+      }
+      return estimatedValues;
+    }
+
+    protected IEnumerable<double> GetMeanModelEstimatedValues(IEnumerable<double> originalValues) {
+      double averageTrainingTarget = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).Average();
+      return Enumerable.Repeat(averageTrainingTarget, originalValues.Count());
+    }
+
+    protected virtual List<double> GetResiduals(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues) {
+      return originalValues.Zip(estimatedValues, (x, y) => Math.Abs(x - y)).ToList();
+    }
+
+    private double CalculateAreaOverCurve(Series series) {
+      if (series.Points.Count < 1) throw new ArgumentException("Could not calculate area under curve if less than 1 data points were given.");
+
+      double auc = 0.0;
+      for (int i = 1; i < series.Points.Count; i++) {
+        double width = series.Points[i].XValue - series.Points[i - 1].XValue;
+        double y1 = 1 - series.Points[i - 1].YValues[0];
+        double y2 = 1 - series.Points[i].YValues[0];
+
+        auc += (y1 + y2) * width / 2;
+      }
+
+      return auc;
+    }
+
+    protected void cmbSamples_SelectedIndexChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)cmbSamples_SelectedIndexChanged, sender, e);
+      else UpdateChart();
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 6647)
@@ -22,15 +22,13 @@
 using System.Linq;
 using System.Windows.Forms;
-using HeuristicLab.Core.Views;
 using HeuristicLab.Data;
 using HeuristicLab.Data.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
-using System.Globalization;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
   [View("Estimated Values")]
   [Content(typeof(IRegressionSolution))]
-  public partial class RegressionSolutionEstimatedValuesView : ItemView, IRegressionSolutionEvaluationView {
+  public partial class RegressionSolutionEstimatedValuesView : DataAnalysisSolutionEvaluationView {
     private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
     private const string ESTIMATEDVALUES_SERIES_NAME = "Estimated Values (all)";
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 6647)
@@ -24,5 +24,4 @@
 using System.Windows.Forms;
 using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -31,5 +30,5 @@
   [View("Line Chart")]
   [Content(typeof(IRegressionSolution))]
-  public partial class RegressionSolutionLineChartView : ItemView, IRegressionSolutionEvaluationView {
+  public partial class RegressionSolutionLineChartView : DataAnalysisSolutionEvaluationView {
     private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
     private const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Values (training)";
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 6647)
@@ -25,5 +25,4 @@
 using System.Windows.Forms;
 using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -32,5 +31,5 @@
   [View("Scatter Plot")]
   [Content(typeof(IRegressionSolution))]
-  public partial class RegressionSolutionScatterPlotView : ItemView, IRegressionSolutionEvaluationView {
+  public partial class RegressionSolutionScatterPlotView : DataAnalysisSolutionEvaluationView {
     private const string ALL_SERIES = "All samples";
     private const string TRAINING_SERIES = "Training samples";
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs	(revision 6647)
@@ -47,4 +47,5 @@
       components = new System.ComponentModel.Container();
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.itemsGroupBox.Text = "Classification Solution";
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs	(revision 6647)
@@ -20,8 +20,6 @@
 #endregion
 
-using System;
 using System.Windows.Forms;
 using HeuristicLab.MainForm;
-using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -31,8 +29,4 @@
     public ClassificationSolutionView() {
       InitializeComponent();
-
-      var classificationSolutionEvaluationViewTypes = ApplicationManager.Manager.GetTypes(typeof(IClassificationSolutionEvaluationView), true);
-      foreach (Type viewType in classificationSolutionEvaluationViewTypes)
-        AddViewListViewItem(viewType, HeuristicLab.Common.Resources.VSImageLibrary.Graph);
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs	(revision 6647)
@@ -20,8 +20,6 @@
 #endregion
 
-using System;
 using System.Windows.Forms;
 using HeuristicLab.MainForm;
-using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -31,8 +29,4 @@
     public ClusteringSolutionView() {
       InitializeComponent();
-
-      var clusteringSolutionEvaluationViewTypes = ApplicationManager.Manager.GetTypes(typeof(IClusteringSolutionEvaluationView), true);
-      foreach (Type viewType in clusteringSolutionEvaluationViewTypes)
-        AddViewListViewItem(viewType, HeuristicLab.Common.Resources.VSImageLibrary.Graph);
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 6647)
@@ -46,16 +46,6 @@
         selectedName = itemsListView.SelectedItems[0].Text;
 
-      //cache old viewTypes;
-      var viewTypes = new List<Tuple<Type, Image>>();
-      foreach (ListViewItem item in ItemsListView.Items) {
-        var viewType = item.Tag as Type;
-        if (viewType != null) viewTypes.Add(Tuple.Create(viewType, imageList.Images[item.ImageIndex]));
-      }
-
       base.OnContentChanged();
-
-      //readd viewTypes
-      foreach (var tuple in viewTypes)
-        AddViewListViewItem(tuple.Item1, tuple.Item2);
+      AddEvaluationViewTypes();
 
       //recover selection
@@ -65,4 +55,13 @@
             item.Selected = true;
         }
+      }
+    }
+
+    protected virtual void AddEvaluationViewTypes() {
+      if (Content != null) {
+        var viewTypes = MainFormManager.GetViewTypes(Content.GetType(), true)
+          .Where(t => typeof(IDataAnalysisSolutionEvaluationView).IsAssignableFrom(t));
+        foreach (var viewType in viewTypes)
+          AddViewListViewItem(viewType, ((IDataAnalysisSolutionEvaluationView)Activator.CreateInstance(viewType)).ViewImage);
       }
     }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs	(revision 6647)
@@ -20,8 +20,6 @@
 #endregion
 
-using System;
 using System.Windows.Forms;
 using HeuristicLab.MainForm;
-using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -31,13 +29,4 @@
     public DiscriminantFunctionClassificationSolutionView() {
       InitializeComponent();
-
-      var classificationSolutionEvaluationViewTypes = ApplicationManager.Manager.GetTypes(typeof(IClassificationSolutionEvaluationView), true);
-      foreach (Type viewType in classificationSolutionEvaluationViewTypes)
-        AddViewListViewItem(viewType, HeuristicLab.Common.Resources.VSImageLibrary.Graph);
-      RemoveViewListViewItem(typeof(ClassificationSolutionEstimatedClassValuesView));
-
-      var regressionSolutionEvaluationViewTypes = ApplicationManager.Manager.GetTypes(typeof(IDiscriminantFunctionClassificationSolutionEvaluationView), true);
-      foreach (Type viewType in regressionSolutionEvaluationViewTypes)
-        AddViewListViewItem(viewType, HeuristicLab.Common.Resources.VSImageLibrary.Graph);
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 6647)
@@ -20,8 +20,6 @@
 #endregion
 
-using System;
 using System.Windows.Forms;
 using HeuristicLab.MainForm;
-using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -31,8 +29,4 @@
     public RegressionSolutionView() {
       InitializeComponent();
-
-      var regressionSolutionEvaluationViewTypes = ApplicationManager.Manager.GetTypes(typeof(IRegressionSolutionEvaluationView), true);
-      foreach (Type viewType in regressionSolutionEvaluationViewTypes)
-        AddViewListViewItem(viewType, HeuristicLab.Common.Resources.VSImageLibrary.Graph);
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 6647)
@@ -139,4 +139,5 @@
     <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" />
     <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" />
+    <Compile Include="OnlineCalculators\OnlineMeanAbsoluteErrorCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineLinearScalingParameterCalculator.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationModel.cs" />
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 6647)
@@ -72,10 +72,14 @@
     private void RegisterEventHandlers() {
       ProblemDataParameter.ValueChanged += new EventHandler(ProblemDataParameter_ValueChanged);
-      if (ProblemDataParameter.Value != null) ProblemDataParameter.Value.Changed += new EventHandler(ProblemDataParameter_ValueChanged);
+      if (ProblemDataParameter.Value != null) ProblemDataParameter.Value.Changed += new EventHandler(ProblemData_Changed);
     }
 
     private void ProblemDataParameter_ValueChanged(object sender, EventArgs e) {
-      ProblemDataParameter.Value.Changed += new EventHandler(ProblemDataParameter_ValueChanged);
+      ProblemDataParameter.Value.Changed += new EventHandler(ProblemData_Changed);
       OnProblemDataChanged();
+      OnReset();
+    }
+
+    private void ProblemData_Changed(object sender, EventArgs e) {
       OnReset();
     }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 6647)
@@ -32,4 +32,6 @@
     private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
     private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
+    private const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
+    private const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
     private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
     private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
@@ -62,4 +64,12 @@
       get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
       private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TrainingMeanAbsoluteError {
+      get { return ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value = value; }
+    }
+    public double TestMeanAbsoluteError {
+      get { return ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value = value; }
     }
     public double TrainingRSquared {
@@ -98,4 +108,6 @@
       Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
       Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
       Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
       Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
@@ -104,4 +116,26 @@
       Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue()));
       Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+
+      #region Backwards compatible code, remove with 3.5
+
+      if (!ContainsKey(TrainingMeanAbsoluteErrorResultName)) {
+        OnlineCalculatorError errorState;
+        Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
+        double trainingMAE = OnlineMeanSquaredErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes), out errorState);
+        TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+      }
+
+      if (!ContainsKey(TestMeanAbsoluteErrorResultName)) {
+        OnlineCalculatorError errorState;
+        Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
+        double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes), out errorState);
+        TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+      }
+      #endregion
     }
 
@@ -117,4 +151,9 @@
       double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
       TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+
+      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
 
       double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 6647)
@@ -26,5 +26,5 @@
     IEnumerable<double> Thresholds { get; }
     IEnumerable<double> ClassValues { get; }
-    // class values and thresholds can only be assigned simultaniously
+    // class values and thresholds can only be assigned simultanously
     void SetThresholdsAndClassValues(IEnumerable<double> thresholds, IEnumerable<double> classValues);
     IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows);
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs	(revision 6647)
@@ -33,4 +33,6 @@
     double TrainingMeanSquaredError { get; }
     double TestMeanSquaredError { get; }
+    double TrainingMeanAbsoluteError { get; }
+    double TestMeanAbsoluteError { get; }
     double TrainingRSquared { get; }
     double TestRSquared { get; }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 6647)
@@ -0,0 +1,90 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineMeanAbsoluteErrorCalculator : IOnlineCalculator {
+
+    private double sae;
+    private int n;
+    public double MeanAbsoluteError {
+      get {
+        return n > 0 ? sae / n : 0.0;
+      }
+    }
+
+    public OnlineMeanAbsoluteErrorCalculator() {
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return MeanAbsoluteError; }
+    }
+    public void Reset() {
+      n = 0;
+      sae = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        double error = estimated - original;
+        sae += Math.Abs(error);
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
+      IEnumerator<double> firstEnumerator = first.GetEnumerator();
+      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+      OnlineMeanAbsoluteErrorCalculator maeCalculator = new OnlineMeanAbsoluteErrorCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
+        double estimated = secondEnumerator.Current;
+        double original = firstEnumerator.Current;
+        maeCalculator.Add(original, estimated);
+        if (maeCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (maeCalculator.ErrorState == OnlineCalculatorError.None &&
+         (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+      } else {
+        errorState = maeCalculator.ErrorState;
+        return maeCalculator.MeanAbsoluteError;
+      }
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3.csproj	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3.csproj	(revision 6647)
@@ -0,0 +1,202 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{5B9B9E8C-2706-43C2-80B8-A08341E431F7}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.QuadraticAssignment.Algorithms</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+    <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="RobustTabooSeachOperator.cs" />
+    <Compile Include="RobustTabooSearch.cs" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
+      <Project>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</Project>
+      <Name>HeuristicLab.Encodings.PermutationEncoding-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
+      <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
+      <Name>HeuristicLab.Operators-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
+      <Project>{25087811-F74C-4128-BC86-8324271DA13E}</Project>
+      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
+      <Project>{102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}</Project>
+      <Name>HeuristicLab.Persistence-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.QuadraticAssignment\3.3\HeuristicLab.Problems.QuadraticAssignment-3.3.csproj">
+      <Project>{79271BC8-4446-40E2-BB89-9BE4E17174FE}</Project>
+      <Name>HeuristicLab.Problems.QuadraticAssignment-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
+      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
+      <Name>HeuristicLab.Random-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+SubWCRev "%25ProjectDir%25\" "%25ProjectDir%25\Plugin.cs.frame" "%25ProjectDir%25\Plugin.cs"</PreBuildEvent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/Plugin.cs.frame
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/Plugin.cs.frame	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/Plugin.cs.frame	(revision 6647)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.QuadraticAssignment.Algorithms {
+  [Plugin("HeuristicLab.Problems.QuadraticAssignment.Algorithms", "3.3.4.$WCREV$")]
+  [PluginFile("HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.PermutationEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.QuadraticAssignment", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabProblemsQuadraticAssignmentAlgorithmsPlugin : PluginBase {
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/Properties/AssemblyInfo.frame
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/Properties/AssemblyInfo.frame	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/Properties/AssemblyInfo.frame	(revision 6647)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Problems.QuadraticAssignment.Algorithms")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2011 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7c14407e-6980-465b-ba3a-4a916d48989b")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.4.$WCREV$")]
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/RobustTabooSeachOperator.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/RobustTabooSeachOperator.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/RobustTabooSeachOperator.cs	(revision 6647)
@@ -0,0 +1,206 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.QuadraticAssignment.Algorithms {
+  [Item("RobustTabooSearchOperator", "Performs an iteration of the robust taboo search algorithm as descrbied in Taillard 1991.")]
+  public sealed class RobustTabooSeachOperator : SingleSuccessorOperator, IIterationBasedOperator, IStochasticOperator {
+
+    #region Parameter Properties
+    public ILookupParameter<IntValue> IterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["Iterations"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<DoubleMatrix> WeightsParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Weights"]; }
+    }
+    public ILookupParameter<DoubleMatrix> DistancesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Distances"]; }
+    }
+    public ILookupParameter<IntMatrix> ShortTermMemoryParameter {
+      get { return (ILookupParameter<IntMatrix>)Parameters["ShortTermMemory"]; }
+    }
+    public ILookupParameter<DoubleMatrix> MoveQualityMatrixParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["MoveQualityMatrix"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> BestQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestQuality"]; }
+    }
+    public ILookupParameter<Swap2Move> LastMoveParameter {
+      get { return (ILookupParameter<Swap2Move>)Parameters["LastMove"]; }
+    }
+    public ILookupParameter<BoolValue> UseNewTabuTenureAdaptionSchemeParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["UseNewTabuTenureAdaptionScheme"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public IValueLookupParameter<IntValue> MinimumTabuTenureParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MinimumTabuTenure"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumTabuTenureParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumTabuTenure"]; }
+    }
+    public IValueLookupParameter<BoolValue> UseAlternativeAspirationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["UseAlternativeAspiration"]; }
+    }
+    public IValueLookupParameter<IntValue> AlternativeAspirationTenureParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["AlternativeAspirationTenure"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private RobustTabooSeachOperator(bool deserializing) : base(deserializing) { }
+    private RobustTabooSeachOperator(RobustTabooSeachOperator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public RobustTabooSeachOperator() {
+      Parameters.Add(new LookupParameter<IntValue>("Iterations", "The current iteration."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation solution."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The weights matrix."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distances matrix."));
+      Parameters.Add(new LookupParameter<IntMatrix>("ShortTermMemory", "The table that stores the iteration at which a certain facility has been assigned to a certain location."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("MoveQualityMatrix", "The quality of all swap moves as evaluated on the current permutation."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value."));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestQuality", "The best quality value."));
+      Parameters.Add(new LookupParameter<Swap2Move>("LastMove", "The last move that was applied."));
+      Parameters.Add(new LookupParameter<BoolValue>("UseNewTabuTenureAdaptionScheme", "True if the new tabu tenure adaption should be used or false otherwise."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "Collection that houses the results of the algorithm."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The number of iterations that the algorithm should run."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MinimumTabuTenure", "The minimum tabu tenure."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumTabuTenure", "The maximum tabu tenure."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("UseAlternativeAspiration", "True if the alternative aspiration condition should be used that takes moves that have not been made for some time above others."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("AlternativeAspirationTenure", "The time t that a move will be remembered for the alternative aspiration condition."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RobustTabooSeachOperator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      IRandom random = RandomParameter.ActualValue;
+      int iteration = IterationsParameter.ActualValue.Value;
+      IntMatrix shortTermMemory = ShortTermMemoryParameter.ActualValue;
+      DoubleMatrix weights = WeightsParameter.ActualValue;
+      DoubleMatrix distances = DistancesParameter.ActualValue;
+      DoubleMatrix moveQualityMatrix = MoveQualityMatrixParameter.ActualValue;
+
+      DoubleValue quality = QualityParameter.ActualValue;
+      DoubleValue bestQuality = BestQualityParameter.ActualValue;
+      if (bestQuality == null) {
+        BestQualityParameter.ActualValue = (DoubleValue)quality.Clone();
+        bestQuality = BestQualityParameter.ActualValue;
+      }
+
+      int minTenure = MinimumTabuTenureParameter.ActualValue.Value;
+      int maxTenure = MaximumTabuTenureParameter.ActualValue.Value;
+      int alternativeAspirationTenure = AlternativeAspirationTenureParameter.ActualValue.Value;
+      bool useAlternativeAspiration = UseAlternativeAspirationParameter.ActualValue.Value;
+      Permutation solution = PermutationParameter.ActualValue;
+      Swap2Move lastMove = LastMoveParameter.ActualValue;
+
+      double bestMoveQuality = double.MaxValue;
+      Swap2Move bestMove = null;
+      bool already_aspired = false;
+
+      foreach (Swap2Move move in ExhaustiveSwap2MoveGenerator.Generate(solution)) {
+        double moveQuality;
+        if (lastMove == null)
+          moveQuality = QAPSwap2MoveEvaluator.Apply(solution, move, weights, distances);
+        else moveQuality = QAPSwap2MoveEvaluator.Apply(solution, move, moveQualityMatrix[move.Index1, move.Index2], weights, distances, lastMove);
+
+        moveQualityMatrix[move.Index1, move.Index2] = moveQuality;
+        moveQualityMatrix[move.Index2, move.Index1] = moveQuality;
+
+        bool autorized = shortTermMemory[move.Index1, solution[move.Index2]] < iteration
+                      || shortTermMemory[move.Index2, solution[move.Index1]] < iteration;
+
+        bool aspired = (shortTermMemory[move.Index1, solution[move.Index2]] < iteration - alternativeAspirationTenure
+                     && shortTermMemory[move.Index2, solution[move.Index1]] < iteration - alternativeAspirationTenure)
+                  || quality.Value + moveQuality < bestQuality.Value;
+
+        if ((aspired && !already_aspired) // the first alternative move is aspired
+          || (aspired && already_aspired && moveQuality < bestMoveQuality) // an alternative move was already aspired, but this is better
+          || (autorized && !aspired && !already_aspired && moveQuality < bestMoveQuality)) { // a regular better move is found
+          bestMove = move;
+          bestMoveQuality = moveQuality;
+          if (aspired) already_aspired = true;
+        }
+      }
+
+      ResultCollection results = ResultsParameter.ActualValue;
+      if (results != null) {
+        IntValue aspiredMoves = null;
+        if (!results.ContainsKey("AspiredMoves")) {
+          aspiredMoves = new IntValue(already_aspired ? 1 : 0);
+          results.Add(new Result("AspiredMoves", "Counts the number of moves that were selected because of the aspiration criteria.", aspiredMoves));
+        } else if (already_aspired) {
+          aspiredMoves = (IntValue)results["AspiredMoves"].Value;
+          aspiredMoves.Value++;
+        }
+      }
+
+      LastMoveParameter.ActualValue = bestMove;
+
+      if (bestMove == null) return base.Apply();
+
+      bool useNewAdaptionScheme = UseNewTabuTenureAdaptionSchemeParameter.ActualValue.Value;
+      if (useNewAdaptionScheme) {
+        double r = random.NextDouble();
+        if (r == 0) r = 1; // transform to (0;1]
+        shortTermMemory[bestMove.Index1, solution[bestMove.Index1]] = (int)(iteration + r * r * r * maxTenure);
+        r = random.NextDouble();
+        if (r == 0) r = 1; // transform to (0;1]
+        shortTermMemory[bestMove.Index2, solution[bestMove.Index2]] = (int)(iteration + r * r * r * maxTenure);
+      } else {
+        shortTermMemory[bestMove.Index1, solution[bestMove.Index1]] = iteration + random.Next(minTenure, maxTenure);
+        shortTermMemory[bestMove.Index2, solution[bestMove.Index2]] = iteration + random.Next(minTenure, maxTenure);
+      }
+      Swap2Manipulator.Apply(solution, bestMove.Index1, bestMove.Index2);
+      quality.Value += bestMoveQuality;
+
+      if (quality.Value < bestQuality.Value) bestQuality.Value = quality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/RobustTabooSearch.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/RobustTabooSearch.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment.Algorithms/3.3/RobustTabooSearch.cs	(revision 6647)
@@ -0,0 +1,395 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.QuadraticAssignment.Algorithms {
+  [Item("Robust Taboo Search", "The algorithm is described in Taillard, E. 1991. Robust Taboo Search for the Quadratic Assignment Problem. Parallel Computing 17, pp. 443-455.")]
+  [Creatable("Algorithms")]
+  [StorableClass]
+  public sealed class RobustTabooSearch : HeuristicOptimizationEngineAlgorithm, IStorableContent {
+    public string Filename { get; set; }
+
+    #region Problem Properties
+    public override Type ProblemType {
+      get { return typeof(QuadraticAssignmentProblem); }
+    }
+    public new QuadraticAssignmentProblem Problem {
+      get { return (QuadraticAssignmentProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+    #endregion
+
+    #region Parameter Properties
+    private FixedValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (FixedValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+    private FixedValueParameter<IntValue> SeedParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["Seed"]; }
+    }
+    private FixedValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (FixedValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
+    }
+    private FixedValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    private FixedValueParameter<IntValue> MinimumTabuTenureParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["MinimumTabuTenure"]; }
+    }
+    private FixedValueParameter<IntValue> MaximumTabuTenureParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["MaximumTabuTenure"]; }
+    }
+    private FixedValueParameter<BoolValue> UseAlternativeAspirationParameter {
+      get { return (FixedValueParameter<BoolValue>)Parameters["UseAlternativeAspiration"]; }
+    }
+    private FixedValueParameter<IntValue> AlternativeAspirationTenureParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["AlternativeAspirationTenure"]; }
+    }
+    private FixedValueParameter<BoolValue> UseNewTabuTenureAdaptionSchemeParameter {
+      get { return (FixedValueParameter<BoolValue>)Parameters["UseNewTabuTenureAdaptionScheme"]; }
+    }
+    #endregion
+
+    #region Properties
+    public int Seed {
+      get { return SeedParameter.Value.Value; }
+      set { SeedParameter.Value.Value = value; }
+    }
+    public bool SetSeedRandomly {
+      get { return SetSeedRandomlyParameter.Value.Value; }
+      set { SetSeedRandomlyParameter.Value.Value = value; }
+    }
+    public int MaximumIterations {
+      get { return MaximumIterationsParameter.Value.Value; }
+      set { MaximumIterationsParameter.Value.Value = value; }
+    }
+    public int MinimumTabuTenure {
+      get { return MinimumTabuTenureParameter.Value.Value; }
+      set { MinimumTabuTenureParameter.Value.Value = value; }
+    }
+    public int MaximumTabuTenure {
+      get { return MaximumTabuTenureParameter.Value.Value; }
+      set { MaximumTabuTenureParameter.Value.Value = value; }
+    }
+    public bool UseAlternativeAspiration {
+      get { return UseAlternativeAspirationParameter.Value.Value; }
+      set { UseAlternativeAspirationParameter.Value.Value = value; }
+    }
+    public int AlternativeAspirationTenure {
+      get { return AlternativeAspirationTenureParameter.Value.Value; }
+      set { AlternativeAspirationTenureParameter.Value.Value = value; }
+    }
+    public bool UseNewTabuTenureAdaptionScheme {
+      get { return UseNewTabuTenureAdaptionSchemeParameter.Value.Value; }
+      set { UseNewTabuTenureAdaptionSchemeParameter.Value.Value = value; }
+    }
+    #endregion
+
+    [Storable]
+    private SolutionsCreator solutionsCreator;
+    [Storable]
+    private RobustTabooSeachOperator mainOperator;
+    [Storable]
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
+
+    [StorableConstructor]
+    private RobustTabooSearch(bool deserializing) : base(deserializing) { }
+    private RobustTabooSearch(RobustTabooSearch original, Cloner cloner)
+      : base(original, cloner) {
+      solutionsCreator = cloner.Clone(original.solutionsCreator);
+      mainOperator = cloner.Clone(original.mainOperator);
+      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
+      RegisterEventHandlers();
+    }
+    public RobustTabooSearch() {
+      Parameters.Add(new FixedValueParameter<MultiAnalyzer>("Analyzer", "The analyzers that are applied after each iteration.", new MultiAnalyzer()));
+      Parameters.Add(new FixedValueParameter<IntValue>("Seed", "The seed value of the random number generator.", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("SetSeedRandomly", "True whether the seed should be set randomly for each run, false if it should be fixed.", new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<IntValue>("MaximumIterations", "The number of iterations that the algorithm should run.", new IntValue(10000)));
+      Parameters.Add(new FixedValueParameter<IntValue>("MinimumTabuTenure", "The minimum tabu tenure.", new IntValue(10)));
+      Parameters.Add(new FixedValueParameter<IntValue>("MaximumTabuTenure", "The maximum tabu tenure.", new IntValue(20)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("UseAlternativeAspiration", "True if the alternative aspiration condition should be used that takes moves that have not been made for some time above others.", new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<IntValue>("AlternativeAspirationTenure", "The time t that a move will be remembered for the alternative aspiration condition.", new IntValue(int.MaxValue)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("TerminateOnOptimalSolution", "True when the algorithm should stop if it reached a quality equal or smaller to the BestKnownQuality.", new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("UseNewTabuTenureAdaptionScheme", @"In an updated version of his implementation, Eric Taillard introduced a different way to change the tabu tenure.
+Instead of setting it uniformly between min and max, it will be set between 0 and max according to a right-skewed distribution.
+Set this option to false if you want to optimize using the earlier 1991 version, and set to true if you want to optimize using the newer version.
+Please note that the MinimumTabuTenure parameter has no effect in the new version.", new BoolValue(true)));
+
+      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      AnalyzerParameter.Value.Operators.Add(qualityAnalyzer);
+
+      RandomCreator randomCreator = new RandomCreator();
+      randomCreator.RandomParameter.ActualName = "Random";
+      randomCreator.SeedParameter.Value = null;
+      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
+      randomCreator.SetSeedRandomlyParameter.Value = null;
+      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
+
+      VariableCreator variableCreator = new VariableCreator();
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
+
+      ResultsCollector resultsCollector = new ResultsCollector();
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations", "The actual iteration."));
+
+      solutionsCreator = new SolutionsCreator();
+      solutionsCreator.NumberOfSolutions = new IntValue(1);
+
+      Placeholder analyzer = new Placeholder();
+      analyzer.Name = "(Analyzer)";
+      analyzer.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
+      UniformSubScopesProcessor ussp = new UniformSubScopesProcessor();
+
+      mainOperator = new RobustTabooSeachOperator();
+      mainOperator.AlternativeAspirationTenureParameter.ActualName = AlternativeAspirationTenureParameter.Name;
+      mainOperator.BestQualityParameter.ActualName = "BestSoFarQuality";
+      mainOperator.IterationsParameter.ActualName = "Iterations";
+      mainOperator.LastMoveParameter.ActualName = "LastMove";
+      mainOperator.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+      mainOperator.MaximumTabuTenureParameter.ActualName = MaximumTabuTenureParameter.Name;
+      mainOperator.MinimumTabuTenureParameter.ActualName = MinimumTabuTenureParameter.Name;
+      mainOperator.MoveQualityMatrixParameter.ActualName = "MoveQualityMatrix";
+      mainOperator.RandomParameter.ActualName = "Random";
+      mainOperator.ResultsParameter.ActualName = "Results";
+      mainOperator.ShortTermMemoryParameter.ActualName = "ShortTermMemory";
+      mainOperator.UseAlternativeAspirationParameter.ActualName = UseAlternativeAspirationParameter.Name;
+
+      ConditionalBranch qualityStopBranch = new ConditionalBranch();
+      qualityStopBranch.Name = "Terminate on optimal quality?";
+      qualityStopBranch.ConditionParameter.ActualName = "TerminateOnOptimalSolution";
+
+      Comparator qualityComparator = new Comparator();
+      qualityComparator.Comparison = new Comparison(ComparisonType.Greater);
+      qualityComparator.LeftSideParameter.ActualName = "BestQuality";
+      qualityComparator.RightSideParameter.ActualName = "BestKnownQuality";
+      qualityComparator.ResultParameter.ActualName = "ContinueByQuality";
+
+      ConditionalBranch continueByQualityBranch = new ConditionalBranch();
+      continueByQualityBranch.ConditionParameter.ActualName = "ContinueByQuality";
+
+      IntCounter iterationsCounter = new IntCounter();
+      iterationsCounter.ValueParameter.ActualName = "Iterations";
+      iterationsCounter.Increment = new IntValue(1);
+
+      Comparator comparator = new Comparator();
+      comparator.Name = "Iterations < MaximumIterations ?";
+      comparator.LeftSideParameter.ActualName = "Iterations";
+      comparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
+      comparator.Comparison = new Comparison(ComparisonType.Less);
+      comparator.ResultParameter.ActualName = "ContinueByIteration";
+
+      ConditionalBranch continueByIterationBranch = new ConditionalBranch();
+      continueByIterationBranch.ConditionParameter.ActualName = "ContinueByIteration";
+
+      OperatorGraph.InitialOperator = randomCreator;
+      randomCreator.Successor = variableCreator;
+      variableCreator.Successor = resultsCollector;
+      resultsCollector.Successor = solutionsCreator;
+      solutionsCreator.Successor = analyzer;
+      analyzer.Successor = ussp;
+      ussp.Operator = mainOperator;
+      ussp.Successor = qualityStopBranch;
+      qualityStopBranch.FalseBranch = iterationsCounter;
+      qualityStopBranch.TrueBranch = qualityComparator;
+      qualityStopBranch.Successor = null;
+      qualityComparator.Successor = continueByQualityBranch;
+      continueByQualityBranch.TrueBranch = iterationsCounter;
+      continueByQualityBranch.FalseBranch = null;
+      continueByQualityBranch.Successor = null;
+      iterationsCounter.Successor = comparator;
+      comparator.Successor = continueByIterationBranch;
+      continueByIterationBranch.TrueBranch = analyzer;
+      continueByIterationBranch.FalseBranch = null;
+      continueByIterationBranch.Successor = null;
+
+      RegisterEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RobustTabooSearch(this, cloner);
+    }
+
+    #region Event Handlers
+    protected override void OnProblemChanged() {
+      base.OnProblemChanged();
+      UpdateProblemSpecificParameters();
+      ParameterizeOperators();
+      UpdateAnalyzers();
+    }
+
+    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
+      base.Problem_EvaluatorChanged(sender, e);
+      ParameterizeOperators();
+      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+    }
+
+    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
+      base.Problem_OperatorsChanged(sender, e);
+      UpdateAnalyzers();
+    }
+
+    protected override void Problem_Reset(object sender, EventArgs e) {
+      base.Problem_Reset(sender, e);
+      UpdateProblemSpecificParameters();
+      ParameterizeOperators();
+      UpdateAnalyzers();
+    }
+
+    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
+      ParameterizeOperators();
+    }
+
+    private void UseAlternativeAspirationParameter_ValueChanged(object sender, EventArgs e) {
+      UpdateAlternativeAspirationTenure();
+    }
+
+    private void AlternativeAspirationTenureParameter_ValueChanged(object sender, EventArgs e) {
+      if (AlternativeAspirationTenure < MaximumIterations && !UseAlternativeAspiration) {
+        SetSilentlyUseAlternativeAspirationParameter(true);
+      } else if (AlternativeAspirationTenure >= MaximumIterations && UseAlternativeAspiration) {
+        SetSilentlyUseAlternativeAspirationParameter(false);
+      }
+    }
+
+    private void MaximumIterationsParameter_ValueChanged(object sender, EventArgs e) {
+      if (MaximumIterations < AlternativeAspirationTenure && UseAlternativeAspiration) {
+        SetSilentlyUseAlternativeAspirationParameter(false);
+      } else if (MaximumIterations >= AlternativeAspirationTenure && !UseAlternativeAspiration) {
+        SetSilentlyUseAlternativeAspirationParameter(true);
+      }
+    }
+
+    private void UseNewTabuTenureAdaptionSchemeParameter_ValueChanged(object sender, EventArgs e) {
+      UpdateProblemSpecificParameters();
+    }
+    #endregion
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      UseAlternativeAspirationParameter.Value.ValueChanged += new EventHandler(UseAlternativeAspirationParameter_ValueChanged);
+      AlternativeAspirationTenureParameter.Value.ValueChanged += new EventHandler(AlternativeAspirationTenureParameter_ValueChanged);
+      MaximumIterationsParameter.Value.ValueChanged += new EventHandler(MaximumIterationsParameter_ValueChanged);
+      UseNewTabuTenureAdaptionSchemeParameter.Value.ValueChanged += new EventHandler(UseNewTabuTenureAdaptionSchemeParameter_ValueChanged);
+    }
+
+    protected override void RegisterProblemEvents() {
+      base.RegisterProblemEvents();
+      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+    }
+
+    protected override void DeregisterProblemEvents() {
+      Problem.Evaluator.QualityParameter.ActualNameChanged -= new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      base.DeregisterProblemEvents();
+    }
+
+    public override void Start() {
+      if (ExecutionState == ExecutionState.Prepared) {
+        int dim = Problem.Weights.Rows;
+        IntMatrix shortTermMemory = new IntMatrix(dim, dim);
+        for (int i = 0; i < dim; i++)
+          for (int j = 0; j < dim; j++) {
+            shortTermMemory[i, j] = -(dim * (i + 1) + j + 1);
+          }
+
+        GlobalScope.Variables.Add(new Variable("ShortTermMemory", shortTermMemory));
+        GlobalScope.Variables.Add(new Variable("MoveQualityMatrix", new DoubleMatrix(dim, dim)));
+      }
+      base.Start();
+    }
+
+    private void UpdateProblemSpecificParameters() {
+      UpdateTabuTenure();
+      UpdateAlternativeAspirationTenure();
+    }
+
+    private void UpdateTabuTenure() {
+      if (UseNewTabuTenureAdaptionScheme) {
+        MinimumTabuTenure = 0;
+        MaximumTabuTenure = 8 * Problem.Weights.Rows;
+      } else {
+        MinimumTabuTenure = (int)(0.9 * Problem.Weights.Rows);
+        MaximumTabuTenure = (int)(1.1 * Problem.Weights.Rows);
+      }
+    }
+
+    private void UpdateAlternativeAspirationTenure() {
+      if (UseAlternativeAspiration) {
+        int n = Problem.Weights.Rows;
+        // Taillard has given two formulas for calculating default values: n^2 / 2 and later n^2 * 5
+        // However these do not really model the values he used in his original publication though
+        // The following formula is a linear regression model on the problem size and parameters
+        // given in Table 3 in Taillard1991 and was lower-bounded artificially by 100
+        AlternativeAspirationTenure = Math.Max(203 * n - 2274, 100);
+      } else {
+        AlternativeAspirationTenure = int.MaxValue;
+      }
+    }
+
+    private void UpdateAnalyzers() {
+      AnalyzerParameter.Value.Operators.Clear();
+      if (Problem != null) {
+        foreach (IAnalyzer analyzer in ((IProblem)Problem).Operators.OfType<IAnalyzer>()) {
+          AnalyzerParameter.Value.Operators.Add(analyzer);
+          if (!(analyzer is BestQAPSolutionAnalyzer))
+            AnalyzerParameter.Value.Operators.SetItemCheckedState(analyzer, false);
+        }
+      }
+      AnalyzerParameter.Value.Operators.Add(qualityAnalyzer);
+    }
+
+    private void ParameterizeOperators() {
+      if (Problem != null) {
+        solutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
+        solutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+
+        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.Name;
+
+        mainOperator.DistancesParameter.ActualName = Problem.DistancesParameter.Name;
+        mainOperator.PermutationParameter.ActualName = Problem.SolutionCreator.PermutationParameter.ActualName;
+        mainOperator.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+        mainOperator.WeightsParameter.ActualName = Problem.WeightsParameter.Name;
+      }
+    }
+
+    private void SetSilentlyUseAlternativeAspirationParameter(bool value) {
+      UseAlternativeAspirationParameter.Value.ValueChanged -= new EventHandler(UseAlternativeAspirationParameter_ValueChanged);
+      UseAlternativeAspiration = value;
+      UseAlternativeAspirationParameter.Value.ValueChanged += new EventHandler(UseAlternativeAspirationParameter_ValueChanged);
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/QAPAlleleFrequencyAnalyzer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/QAPAlleleFrequencyAnalyzer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/QAPAlleleFrequencyAnalyzer.cs	(revision 6647)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
@@ -56,17 +57,19 @@
 
     protected override Allele[] CalculateAlleles(Permutation solution) {
-      Allele[] alleles = new Allele[solution.Length];
+      Allele[] alleles = new Allele[solution.Length * solution.Length];
+      Dictionary<string, int> allelesDict = new Dictionary<string, int>();
       DoubleMatrix weights = WeightsParameter.ActualValue;
       DoubleMatrix distances = DistancesParameter.ActualValue;
-      int source, target;
       double impact;
 
-      for (int i = 0; i < solution.Length; i++) {
-        source = i;
-        target = solution[i];
-        impact = 0;
-        for (int j = 0; j < solution.Length; j++)
-          impact += weights[source, j] * distances[target, solution[j]];
-        alleles[i] = new Allele(source.ToString() + "->" + target.ToString(), impact);
+      for (int x = 0; x < solution.Length; x++) {
+        for (int y = 0; y < solution.Length; y++) {
+          string allele = weights[x, y].ToString() + ">" + distances[solution[x], solution[y]].ToString();
+          int repetition = 1;
+          if (allelesDict.ContainsKey(allele)) repetition += allelesDict[allele];
+          allelesDict[allele] = repetition;
+          impact = weights[x, y] * distances[solution[x], solution[y]];
+          alleles[x * solution.Length + y] = new Allele(allele + "/" + repetition, impact);
+        }
       }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/QAPPopulationDiversityAnalyzer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/QAPPopulationDiversityAnalyzer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/QAPPopulationDiversityAnalyzer.cs	(revision 6647)
@@ -23,5 +23,7 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -33,8 +35,23 @@
   [StorableClass]
   public sealed class QAPPopulationDiversityAnalyzer : PopulationDiversityAnalyzer<Permutation> {
+    public IValueParameter<BoolValue> UsePhenotypeSimilarityParameter {
+      get { return (IValueParameter<BoolValue>)Parameters["UsePhenotypeSimilarity"]; }
+    }
+    public ILookupParameter<DoubleMatrix> WeightsParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Weights"]; }
+    }
+    public ILookupParameter<DoubleMatrix> DistancesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Distances"]; }
+    }
+
     [StorableConstructor]
     private QAPPopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { }
     private QAPPopulationDiversityAnalyzer(QAPPopulationDiversityAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public QAPPopulationDiversityAnalyzer() : base() { }
+    public QAPPopulationDiversityAnalyzer()
+      : base() {
+      Parameters.Add(new ValueParameter<BoolValue>("UsePhenotypeSimilarity", "True if the similarity should be measured a level closer to the phenotype (the number of similar assignments of individual weights to distances). Set to false if the number of equal assignments (facility to location) should be counted.", new BoolValue(false)));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The weights matrix."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distances matrix."));
+    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -42,5 +59,20 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey("UsePhenotypeSimilarity"))
+        Parameters.Add(new ValueParameter<BoolValue>("UsePhenotypeSimilarity", "True if the similarity should be measured a level closer to the phenotype (the number of similar assignments of individual weights to distances). Set to false if the number of equal assignments (facility to location) should be counted.", new BoolValue(false)));
+      if (!Parameters.ContainsKey("Weights"))
+        Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The weights matrix."));
+      if (!Parameters.ContainsKey("Distances"))
+        Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distances matrix."));
+      #endregion
+    }
+
     protected override double[,] CalculateSimilarities(Permutation[] solutions) {
+      DoubleMatrix weights = WeightsParameter.ActualValue, distances = DistancesParameter.ActualValue;
+      bool phenotypeSimilarity = UsePhenotypeSimilarityParameter.Value.Value;
       int count = solutions.Length;
       double[,] similarities = new double[count, count];
@@ -49,5 +81,7 @@
         similarities[i, i] = 1;
         for (int j = i + 1; j < count; j++) {
-          similarities[i, j] = CalculateSimilarity(solutions[i], solutions[j]);
+          if (phenotypeSimilarity)
+            similarities[i, j] = QAPPermutationProximityCalculator.CalculatePhenotypeSimilarity(solutions[i], solutions[j], weights, distances);
+          else similarities[i, j] = QAPPermutationProximityCalculator.CalculateGenotypeSimilarity(solutions[i], solutions[j]);
           similarities[j, i] = similarities[i, j];
         }
@@ -55,13 +89,4 @@
       return similarities;
     }
-
-    private double CalculateSimilarity(Permutation assignment1, Permutation assignment2) {
-      int identicalAssignments = 0;
-      for (int i = 0; i < assignment1.Length; i++) {
-        if (assignment1[i] == assignment2[i])
-          identicalAssignments++;
-      }
-      return ((double)identicalAssignments) / assignment1.Length;
-    }
   }
 }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPSwap2MoveEvaluator.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPSwap2MoveEvaluator.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPSwap2MoveEvaluator.cs	(revision 6647)
@@ -49,4 +49,13 @@
     }
 
+    /// <summary>
+    /// Calculates the quality of the move <paramref name="move"/> by evaluating the changes.
+    /// The runtime complexity of this method is O(N) with N being the size of the permutation.
+    /// </summary>
+    /// <param name="assignment">The current permutation.</param>
+    /// <param name="move">The move that is to be evaluated if it was applied to the current permutation.</param>
+    /// <param name="weights">The weights matrix.</param>
+    /// <param name="distances">The distances matrix.</param>
+    /// <returns>The relative change in quality if <paramref name="move"/> was applied to <paramref name="assignment"/>.</returns>
     public static double Apply(Permutation assignment, Swap2Move move, DoubleMatrix weights, DoubleMatrix distances) {
       if (move.Index1 == move.Index2) return 0;
@@ -73,4 +82,42 @@
     }
 
+    /// <summary>
+    /// Is able to compute the move qualities faster O(1) in some cases if it knows the quality of
+    /// performing the move <paramref name="move"/> previously. In other cases it performs a
+    /// standard move quality calculation with runtime complexity O(N).
+    /// </summary>
+    /// <remarks>
+    /// The number of cases that the calculation can be performed faster grows with N^2
+    /// while the number of cases which require a larger recalculation grows linearly with N.
+    /// Larger problem instances thus benefit from this faster method to a larger degree.
+    /// </remarks>
+    /// <param name="assignment">The current permutation.</param>
+    /// <param name="move">The current move that is to be evaluated.</param>
+    /// <param name="previousQuality">The quality of that move as evaluated for the previous permutation.</param>
+    /// <param name="weights">The weigths matrix.</param>
+    /// <param name="distances">The distances matrix.</param>
+    /// <param name="lastMove">The move that was applied to transform the permutation from the previous to the current one.</param>
+    /// <returns>The relative change in quality if <paramref name="move"/> was applied to <paramref name="assignment"/>.</returns>
+    public static double Apply(Permutation assignment, Swap2Move move, double previousQuality,
+      DoubleMatrix weights, DoubleMatrix distances, Swap2Move lastMove) {
+      bool overlapsLastMove = move.Index1 == lastMove.Index1
+                           || move.Index2 == lastMove.Index1
+                           || move.Index1 == lastMove.Index2
+                           || move.Index2 == lastMove.Index2;
+
+      if (!overlapsLastMove) {
+        int r = lastMove.Index1, u = move.Index1, s = lastMove.Index2, v = move.Index2;
+        int pR = assignment[lastMove.Index1], pU = assignment[move.Index1], pS = assignment[lastMove.Index2], pV = assignment[move.Index2];
+
+        return previousQuality
+          + (weights[r, u] - weights[r, v] + weights[s, v] - weights[s, u])
+            * (distances[pS, pU] - distances[pS, pV] + distances[pR, pV] - distances[pR, pU])
+          + (weights[u, r] - weights[v, r] + weights[v, s] - weights[u, s])
+            * (distances[pU, pS] - distances[pV, pS] + distances[pV, pR] - distances[pU, pR]);
+      } else {
+        return Apply(assignment, move, weights, distances);
+      }
+    }
+
     public override IOperation Apply() {
       Swap2Move move = Swap2MoveParameter.ActualValue;
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/HeuristicLab.Problems.QuadraticAssignment-3.3.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/HeuristicLab.Problems.QuadraticAssignment-3.3.csproj	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/HeuristicLab.Problems.QuadraticAssignment-3.3.csproj	(revision 6647)
@@ -124,4 +124,5 @@
     <Compile Include="Parsers\QAPLIBParser.cs" />
     <Compile Include="QAPAssignment.cs" />
+    <Compile Include="QAPPermutationProximityCalculator.cs" />
     <Compile Include="QuadraticAssignmentProblem.cs" />
     <EmbeddedResource Include="Data\bur26a.dat" />
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPPermutationProximityCalculator.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPPermutationProximityCalculator.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPPermutationProximityCalculator.cs	(revision 6647)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Collections.Generic;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+
+namespace HeuristicLab.Problems.QuadraticAssignment {
+  public static class QAPPermutationProximityCalculator {
+
+    public static double CalculateGenotypeSimilarity(Permutation a, Permutation b) {
+      int similar = 0;
+      for (int i = 0; i < a.Length; i++) {
+        if (a[i] == b[i]) similar++;
+      }
+      return similar / (double)a.Length;
+    }
+
+    public static double CalculateGenotypeDistance(Permutation a, Permutation b) {
+      return 1.0 - CalculateGenotypeSimilarity(a, b);
+    }
+
+    public static double CalculatePhenotypeSimilarity(Permutation a, Permutation b, DoubleMatrix weights, DoubleMatrix distances) {
+      return 1.0 - CalculatePhenotypeDistance(a, b, weights, distances);
+    }
+
+    public static double CalculatePhenotypeDistance(Permutation a, Permutation b, DoubleMatrix weights, DoubleMatrix distances) {
+      Dictionary<double, Dictionary<double, int>> alleles = new Dictionary<double, Dictionary<double, int>>();
+      int distance = 0, len = a.Length;
+      for (int x = 0; x < len; x++) {
+        for (int y = 0; y < len; y++) {
+          // there's a limited universe of double values as they're all drawn from the same matrix
+          double dA = distances[a[x], a[y]], dB = distances[b[x], b[y]];
+          if (dA == dB) continue;
+
+          Dictionary<double, int> dAlleles;
+          if (!alleles.ContainsKey(weights[x, y])) {
+            dAlleles = new Dictionary<double, int>();
+            alleles.Add(weights[x, y], dAlleles);
+          } else dAlleles = alleles[weights[x, y]];
+
+          int countA = 1, countB = -1;
+
+          if (dAlleles.ContainsKey(dA)) countA += dAlleles[dA];
+          if (dAlleles.ContainsKey(dB)) countB += dAlleles[dB];
+
+          if (countA <= 0) distance--; // we've found in A an allele that was present in B
+          else distance++; // we've found in A a new allele
+          dAlleles[dA] = countA;
+
+          if (countB >= 0) distance--; // we've found in B an allele that was present in A
+          else distance++; // we've found in B a new allele
+          dAlleles[dB] = countB;
+        }
+      }
+      return distance / (double)(2 * len * len);
+    }
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 6647)
@@ -385,6 +385,6 @@
         Distances = new DoubleMatrix(parser.Distances);
         Weights = new DoubleMatrix(parser.Weights);
-        Name = "Quadratic Assignment Problem (loaded instance " + instance + ")";
-        Description = "Loaded embedded problem data of instance " + instance + ".";
+        Name = instance;
+        Description = "Loaded embedded QAPLIB problem data of instance " + instance + ".";
         OnReset();
       }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPMoveEvaluatorTest.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPMoveEvaluatorTest.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPMoveEvaluatorTest.cs	(revision 6647)
@@ -60,27 +60,67 @@
       for (int i = 0; i < ProblemSize - 1; i++) {
         for (int j = i + 1; j < ProblemSize; j++) {
-          symmetricDistances[i, j] = random.Next(ProblemSize);
+          symmetricDistances[i, j] = random.Next(ProblemSize * 100);
           symmetricDistances[j, i] = symmetricDistances[i, j];
-          symmetricWeights[i, j] = random.Next(ProblemSize);
+          symmetricWeights[i, j] = random.Next(ProblemSize * 100);
           symmetricWeights[j, i] = symmetricWeights[i, j];
-          asymmetricDistances[i, j] = random.Next(ProblemSize);
-          asymmetricDistances[j, i] = random.Next(ProblemSize);
-          asymmetricWeights[i, j] = random.Next(ProblemSize);
-          asymmetricWeights[j, i] = random.Next(ProblemSize);
-          nonZeroDiagonalDistances[i, j] = random.Next(ProblemSize);
-          nonZeroDiagonalDistances[j, i] = random.Next(ProblemSize);
-          nonZeroDiagonalWeights[i, j] = random.Next(ProblemSize);
-          nonZeroDiagonalWeights[j, i] = random.Next(ProblemSize);
+          asymmetricDistances[i, j] = random.Next(ProblemSize * 100);
+          asymmetricDistances[j, i] = random.Next(ProblemSize * 100);
+          asymmetricWeights[i, j] = random.Next(ProblemSize * 100);
+          asymmetricWeights[j, i] = random.Next(ProblemSize * 100);
+          nonZeroDiagonalDistances[i, j] = random.Next(ProblemSize * 100);
+          nonZeroDiagonalDistances[j, i] = random.Next(ProblemSize * 100);
+          nonZeroDiagonalWeights[i, j] = random.Next(ProblemSize * 100);
+          nonZeroDiagonalWeights[j, i] = random.Next(ProblemSize * 100);
         }
-        nonZeroDiagonalDistances[i, i] = random.Next(ProblemSize);
-        nonZeroDiagonalWeights[i, i] = random.Next(ProblemSize);
+        nonZeroDiagonalDistances[i, i] = random.Next(ProblemSize * 100);
+        nonZeroDiagonalWeights[i, i] = random.Next(ProblemSize * 100);
       }
       int index = random.Next(ProblemSize);
       if (nonZeroDiagonalDistances[index, index] == 0)
-        nonZeroDiagonalDistances[index, index] = random.Next(1, ProblemSize);
+        nonZeroDiagonalDistances[index, index] = random.Next(1, ProblemSize * 100);
       index = random.Next(ProblemSize);
       if (nonZeroDiagonalWeights[index, index] == 0)
-        nonZeroDiagonalWeights[index, index] = random.Next(1, ProblemSize);
+        nonZeroDiagonalWeights[index, index] = random.Next(1, ProblemSize * 100);
       assignment = new Permutation(PermutationTypes.Absolute, ProblemSize, random);
+    }
+
+    [TestMethod]
+    public void Swap2MoveEvaluatorFastEvaluationTest() {
+
+      for (int i = 0; i < 500; i++) {
+        Swap2Move lastMove = new Swap2Move(random.Next(ProblemSize), random.Next(ProblemSize));
+        Permutation prevAssignment = (Permutation)assignment.Clone();
+        Swap2Manipulator.Apply(assignment, lastMove.Index1, lastMove.Index2);
+        Permutation nextAssignment = (Permutation)assignment.Clone();
+        Swap2Move currentMove = new Swap2Move(random.Next(ProblemSize), random.Next(ProblemSize));
+        Swap2Manipulator.Apply(nextAssignment, currentMove.Index1, currentMove.Index2);
+
+        double moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, symmetricWeights, symmetricDistances);
+        double moveAfter = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
+                moveBefore, symmetricWeights, symmetricDistances, lastMove);
+        double before = QAPEvaluator.Apply(assignment, symmetricWeights, symmetricDistances);
+        double after = QAPEvaluator.Apply(nextAssignment, symmetricWeights, symmetricDistances);
+
+        Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on symmetric matrices: " + Environment.NewLine
+          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");
+
+        moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, asymmetricWeights, asymmetricDistances);
+        moveAfter = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
+                moveBefore, asymmetricWeights, asymmetricDistances, lastMove);
+        before = QAPEvaluator.Apply(assignment, asymmetricWeights, asymmetricDistances);
+        after = QAPEvaluator.Apply(nextAssignment, asymmetricWeights, asymmetricDistances);
+
+        Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on asymmetric matrices: " + Environment.NewLine
+          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");
+
+        moveBefore = QAPSwap2MoveEvaluator.Apply(prevAssignment, currentMove, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
+        moveAfter = QAPSwap2MoveEvaluator.Apply(assignment, currentMove,
+                moveBefore, nonZeroDiagonalWeights, nonZeroDiagonalDistances, lastMove);
+        before = QAPEvaluator.Apply(assignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
+        after = QAPEvaluator.Apply(nextAssignment, nonZeroDiagonalWeights, nonZeroDiagonalDistances);
+
+        Assert.IsTrue(moveAfter.IsAlmost(after - before), "Failed on non-zero diagonal matrices: " + Environment.NewLine
+          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveAfter + ".");
+      }
     }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.Designer.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.Designer.cs	(revision 6647)
@@ -50,4 +50,5 @@
       this.copyImageToClipboardBitmapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
       this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
+      this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
       this.contextMenuStrip.SuspendLayout();
       ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
@@ -58,7 +59,8 @@
       this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.exportChartToolStripMenuItem,
+            this.exportToolStripMenuItem,
             this.copyImageToClipboardBitmapToolStripMenuItem});
       this.contextMenuStrip.Name = "contextMenuStrip";
-      this.contextMenuStrip.Size = new System.Drawing.Size(257, 76);
+      this.contextMenuStrip.Size = new System.Drawing.Size(257, 70);
       // 
       // exportChartToolStripMenuItem
@@ -66,5 +68,5 @@
       this.exportChartToolStripMenuItem.Name = "exportChartToolStripMenuItem";
       this.exportChartToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
-      this.exportChartToolStripMenuItem.Text = "Export Chart";
+      this.exportChartToolStripMenuItem.Text = "Quick Export Chart";
       this.exportChartToolStripMenuItem.Click += new System.EventHandler(this.exportChartToolStripMenuItem_Click);
       // 
@@ -81,4 +83,11 @@
           "*.gif)|*.gif|TIFF (*.tif)|*.tif\"";
       this.saveFileDialog.FilterIndex = 2;
+      // 
+      // exportToolStripMenuItem
+      // 
+      this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
+      this.exportToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+      this.exportToolStripMenuItem.Text = "Export Chart...";
+      this.exportToolStripMenuItem.Click += new System.EventHandler(this.exportToolStripMenuItem_Click);
       // 
       // EnhancedChart
@@ -97,4 +106,5 @@
     private System.Windows.Forms.ToolStripMenuItem copyImageToClipboardBitmapToolStripMenuItem;
     private System.Windows.Forms.SaveFileDialog saveFileDialog;
+    private System.Windows.Forms.ToolStripMenuItem exportToolStripMenuItem;
   }
 }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs	(revision 6647)
@@ -28,7 +28,10 @@
 namespace HeuristicLab.Visualization.ChartControlsExtensions {
   public partial class EnhancedChart : Chart {
+    private ImageExportDialog exportDialog;
+
     public EnhancedChart()
       : base() {
       InitializeComponent();
+      exportDialog = new ImageExportDialog(this);
       EnableDoubleClickResetsZoom = true;
       EnableMiddleClickPanning = true;
@@ -138,5 +141,5 @@
     #endregion
 
-    private void exportChartToolStripMenuItem_Click(object sender, System.EventArgs e) {
+    private void exportChartToolStripMenuItem_Click(object sender, EventArgs e) {
       // Set image file format
       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
@@ -162,5 +165,9 @@
     }
 
-    private void copyImageToClipboardBitmapToolStripMenuItem_Click(object sender, System.EventArgs e) {
+    private void exportToolStripMenuItem_Click(object sender, EventArgs e) {
+      exportDialog.ShowDialog();
+    }
+
+    private void copyImageToClipboardBitmapToolStripMenuItem_Click(object sender, EventArgs e) {
       System.IO.MemoryStream stream = new System.IO.MemoryStream();
       SaveImage(stream, System.Drawing.Imaging.ImageFormat.Bmp);
Index: /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj	(revision 6647)
@@ -128,4 +128,10 @@
       <DependentUpon>HistogramControl.cs</DependentUpon>
     </Compile>
+    <Compile Include="ImageExportDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="ImageExportDialog.Designer.cs">
+      <DependentUpon>ImageExportDialog.cs</DependentUpon>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
Index: /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.Designer.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.Designer.cs	(revision 6647)
@@ -0,0 +1,724 @@
+﻿namespace HeuristicLab.Visualization.ChartControlsExtensions {
+  partial class ImageExportDialog {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.titleTextBox = new System.Windows.Forms.TextBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.okButton = new System.Windows.Forms.Button();
+      this.label2 = new System.Windows.Forms.Label();
+      this.secondaryXTextBox = new System.Windows.Forms.TextBox();
+      this.label3 = new System.Windows.Forms.Label();
+      this.secondaryYTextBox = new System.Windows.Forms.TextBox();
+      this.label4 = new System.Windows.Forms.Label();
+      this.resolutionComboBox = new System.Windows.Forms.ComboBox();
+      this.widthNumericUD = new System.Windows.Forms.NumericUpDown();
+      this.label5 = new System.Windows.Forms.Label();
+      this.label6 = new System.Windows.Forms.Label();
+      this.axisFontSizeComboBox = new System.Windows.Forms.ComboBox();
+      this.scalesFontSizeComboBox = new System.Windows.Forms.ComboBox();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.label9 = new System.Windows.Forms.Label();
+      this.label10 = new System.Windows.Forms.Label();
+      this.groupBox1 = new System.Windows.Forms.GroupBox();
+      this.groupBox2 = new System.Windows.Forms.GroupBox();
+      this.primaryXTextBox = new System.Windows.Forms.TextBox();
+      this.primaryYTextBox = new System.Windows.Forms.TextBox();
+      this.label14 = new System.Windows.Forms.Label();
+      this.label15 = new System.Windows.Forms.Label();
+      this.groupBox3 = new System.Windows.Forms.GroupBox();
+      this.label18 = new System.Windows.Forms.Label();
+      this.label12 = new System.Windows.Forms.Label();
+      this.label11 = new System.Windows.Forms.Label();
+      this.label7 = new System.Windows.Forms.Label();
+      this.legendFontSizeComboBox = new System.Windows.Forms.ComboBox();
+      this.label17 = new System.Windows.Forms.Label();
+      this.titleFontSizeComboBox = new System.Windows.Forms.ComboBox();
+      this.label16 = new System.Windows.Forms.Label();
+      this.heightNumericUD = new System.Windows.Forms.NumericUpDown();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.chartAreaComboBox = new System.Windows.Forms.ComboBox();
+      this.togglePreviewCheckBox = new System.Windows.Forms.CheckBox();
+      this.lengthUnitComboBox = new System.Windows.Forms.ComboBox();
+      this.resolutionUnitComboBox = new System.Windows.Forms.ComboBox();
+      this.label8 = new System.Windows.Forms.Label();
+      this.previewPictureBox = new System.Windows.Forms.PictureBox();
+      this.label13 = new System.Windows.Forms.Label();
+      this.previewZoomLabel = new System.Windows.Forms.Label();
+      this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
+      ((System.ComponentModel.ISupportInitialize)(this.widthNumericUD)).BeginInit();
+      this.groupBox1.SuspendLayout();
+      this.groupBox2.SuspendLayout();
+      this.groupBox3.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.heightNumericUD)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // titleTextBox
+      // 
+      this.titleTextBox.Location = new System.Drawing.Point(62, 11);
+      this.titleTextBox.Name = "titleTextBox";
+      this.titleTextBox.Size = new System.Drawing.Size(203, 20);
+      this.titleTextBox.TabIndex = 1;
+      this.titleTextBox.TextChanged += new System.EventHandler(this.titleTextBox_TextChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(6, 22);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(30, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "Title:";
+      // 
+      // okButton
+      // 
+      this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+      this.okButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.okButton.Location = new System.Drawing.Point(141, 487);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 13;
+      this.okButton.Text = "Save";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.okButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(10, 14);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(30, 13);
+      this.label2.TabIndex = 0;
+      this.label2.Text = "Title:";
+      // 
+      // secondaryXTextBox
+      // 
+      this.secondaryXTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.secondaryXTextBox.Location = new System.Drawing.Point(49, 27);
+      this.secondaryXTextBox.Name = "secondaryXTextBox";
+      this.secondaryXTextBox.Size = new System.Drawing.Size(203, 20);
+      this.secondaryXTextBox.TabIndex = 1;
+      this.secondaryXTextBox.TextChanged += new System.EventHandler(this.secondaryXTextBox_TextChanged);
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(6, 30);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(23, 13);
+      this.label3.TabIndex = 0;
+      this.label3.Text = "X2:";
+      // 
+      // secondaryYTextBox
+      // 
+      this.secondaryYTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.secondaryYTextBox.Location = new System.Drawing.Point(49, 53);
+      this.secondaryYTextBox.Name = "secondaryYTextBox";
+      this.secondaryYTextBox.Size = new System.Drawing.Size(203, 20);
+      this.secondaryYTextBox.TabIndex = 3;
+      this.secondaryYTextBox.TextChanged += new System.EventHandler(this.secondaryYTextBox_TextChanged);
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(6, 56);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(23, 13);
+      this.label4.TabIndex = 2;
+      this.label4.Text = "Y2:";
+      // 
+      // resolutionComboBox
+      // 
+      this.resolutionComboBox.FormattingEnabled = true;
+      this.resolutionComboBox.Items.AddRange(new object[] {
+            "72",
+            "96",
+            "150",
+            "300",
+            "600"});
+      this.resolutionComboBox.Location = new System.Drawing.Point(76, 383);
+      this.resolutionComboBox.Name = "resolutionComboBox";
+      this.resolutionComboBox.Size = new System.Drawing.Size(75, 21);
+      this.resolutionComboBox.TabIndex = 6;
+      this.resolutionComboBox.TextChanged += new System.EventHandler(this.resolutionComboBox_TextChanged);
+      this.resolutionComboBox.Validating += new System.ComponentModel.CancelEventHandler(this.resolutionComboBox_Validating);
+      // 
+      // widthNumericUD
+      // 
+      this.widthNumericUD.DecimalPlaces = 2;
+      this.widthNumericUD.Increment = new decimal(new int[] {
+            5,
+            0,
+            0,
+            65536});
+      this.widthNumericUD.Location = new System.Drawing.Point(76, 410);
+      this.widthNumericUD.Maximum = new decimal(new int[] {
+            1000,
+            0,
+            0,
+            0});
+      this.widthNumericUD.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            131072});
+      this.widthNumericUD.Name = "widthNumericUD";
+      this.widthNumericUD.Size = new System.Drawing.Size(75, 20);
+      this.widthNumericUD.TabIndex = 8;
+      this.widthNumericUD.Value = new decimal(new int[] {
+            8,
+            0,
+            0,
+            0});
+      this.widthNumericUD.ValueChanged += new System.EventHandler(this.widthNumericUD_ValueChanged);
+      // 
+      // label5
+      // 
+      this.label5.AutoSize = true;
+      this.label5.Location = new System.Drawing.Point(10, 386);
+      this.label5.Name = "label5";
+      this.label5.Size = new System.Drawing.Size(60, 13);
+      this.label5.TabIndex = 5;
+      this.label5.Text = "Resolution:";
+      // 
+      // label6
+      // 
+      this.label6.AutoSize = true;
+      this.label6.Location = new System.Drawing.Point(10, 412);
+      this.label6.Name = "label6";
+      this.label6.Size = new System.Drawing.Size(38, 13);
+      this.label6.TabIndex = 7;
+      this.label6.Text = "Width:";
+      // 
+      // axisFontSizeComboBox
+      // 
+      this.axisFontSizeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.axisFontSizeComboBox.FormattingEnabled = true;
+      this.axisFontSizeComboBox.Items.AddRange(new object[] {
+            "6",
+            "8",
+            "10",
+            "11",
+            "12",
+            "14",
+            "16",
+            "18",
+            "24",
+            "36",
+            "72"});
+      this.axisFontSizeComboBox.Location = new System.Drawing.Point(54, 46);
+      this.axisFontSizeComboBox.Name = "axisFontSizeComboBox";
+      this.axisFontSizeComboBox.Size = new System.Drawing.Size(84, 21);
+      this.axisFontSizeComboBox.TabIndex = 3;
+      this.axisFontSizeComboBox.TextChanged += new System.EventHandler(this.axisFontSizeComboBox_TextChanged);
+      this.axisFontSizeComboBox.Validating += new System.ComponentModel.CancelEventHandler(this.numericComboBox_Validating);
+      // 
+      // scalesFontSizeComboBox
+      // 
+      this.scalesFontSizeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.scalesFontSizeComboBox.FormattingEnabled = true;
+      this.scalesFontSizeComboBox.Items.AddRange(new object[] {
+            "4",
+            "5",
+            "6",
+            "7",
+            "8",
+            "9",
+            "10",
+            "11",
+            "12",
+            "14",
+            "16",
+            "18",
+            "24",
+            "36",
+            "72"});
+      this.scalesFontSizeComboBox.Location = new System.Drawing.Point(54, 73);
+      this.scalesFontSizeComboBox.Name = "scalesFontSizeComboBox";
+      this.scalesFontSizeComboBox.Size = new System.Drawing.Size(84, 21);
+      this.scalesFontSizeComboBox.TabIndex = 5;
+      this.scalesFontSizeComboBox.TextChanged += new System.EventHandler(this.scalesFontSizeComboBox_TextChanged);
+      this.scalesFontSizeComboBox.Validating += new System.ComponentModel.CancelEventHandler(this.numericComboBox_Validating);
+      // 
+      // cancelButton
+      // 
+      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+      this.cancelButton.Location = new System.Drawing.Point(222, 487);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 14;
+      this.cancelButton.Text = "Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+      // 
+      // label9
+      // 
+      this.label9.AutoSize = true;
+      this.label9.Location = new System.Drawing.Point(6, 51);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(29, 13);
+      this.label9.TabIndex = 2;
+      this.label9.Text = "Axis:";
+      // 
+      // label10
+      // 
+      this.label10.AutoSize = true;
+      this.label10.Location = new System.Drawing.Point(6, 78);
+      this.label10.Name = "label10";
+      this.label10.Size = new System.Drawing.Size(42, 13);
+      this.label10.TabIndex = 4;
+      this.label10.Text = "Scales:";
+      // 
+      // groupBox1
+      // 
+      this.groupBox1.Controls.Add(this.secondaryXTextBox);
+      this.groupBox1.Controls.Add(this.secondaryYTextBox);
+      this.groupBox1.Controls.Add(this.label4);
+      this.groupBox1.Controls.Add(this.label3);
+      this.groupBox1.Location = new System.Drawing.Point(12, 154);
+      this.groupBox1.Name = "groupBox1";
+      this.groupBox1.Size = new System.Drawing.Size(258, 82);
+      this.groupBox1.TabIndex = 3;
+      this.groupBox1.TabStop = false;
+      this.groupBox1.Text = "Secondary Axis";
+      // 
+      // groupBox2
+      // 
+      this.groupBox2.Controls.Add(this.primaryXTextBox);
+      this.groupBox2.Controls.Add(this.primaryYTextBox);
+      this.groupBox2.Controls.Add(this.label14);
+      this.groupBox2.Controls.Add(this.label15);
+      this.groupBox2.Location = new System.Drawing.Point(12, 64);
+      this.groupBox2.Name = "groupBox2";
+      this.groupBox2.Size = new System.Drawing.Size(258, 84);
+      this.groupBox2.TabIndex = 2;
+      this.groupBox2.TabStop = false;
+      this.groupBox2.Text = "Primary Axis";
+      // 
+      // primaryXTextBox
+      // 
+      this.primaryXTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.primaryXTextBox.Location = new System.Drawing.Point(49, 27);
+      this.primaryXTextBox.Name = "primaryXTextBox";
+      this.primaryXTextBox.Size = new System.Drawing.Size(203, 20);
+      this.primaryXTextBox.TabIndex = 1;
+      this.primaryXTextBox.TextChanged += new System.EventHandler(this.primaryXTextBox_TextChanged);
+      // 
+      // primaryYTextBox
+      // 
+      this.primaryYTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.primaryYTextBox.Location = new System.Drawing.Point(49, 53);
+      this.primaryYTextBox.Name = "primaryYTextBox";
+      this.primaryYTextBox.Size = new System.Drawing.Size(203, 20);
+      this.primaryYTextBox.TabIndex = 3;
+      this.primaryYTextBox.TextChanged += new System.EventHandler(this.primaryYTextBox_TextChanged);
+      // 
+      // label14
+      // 
+      this.label14.AutoSize = true;
+      this.label14.Location = new System.Drawing.Point(6, 56);
+      this.label14.Name = "label14";
+      this.label14.Size = new System.Drawing.Size(17, 13);
+      this.label14.TabIndex = 2;
+      this.label14.Text = "Y:";
+      // 
+      // label15
+      // 
+      this.label15.AutoSize = true;
+      this.label15.Location = new System.Drawing.Point(6, 30);
+      this.label15.Name = "label15";
+      this.label15.Size = new System.Drawing.Size(17, 13);
+      this.label15.TabIndex = 0;
+      this.label15.Text = "X:";
+      // 
+      // groupBox3
+      // 
+      this.groupBox3.Controls.Add(this.label18);
+      this.groupBox3.Controls.Add(this.label12);
+      this.groupBox3.Controls.Add(this.label11);
+      this.groupBox3.Controls.Add(this.label7);
+      this.groupBox3.Controls.Add(this.label1);
+      this.groupBox3.Controls.Add(this.label9);
+      this.groupBox3.Controls.Add(this.legendFontSizeComboBox);
+      this.groupBox3.Controls.Add(this.label17);
+      this.groupBox3.Controls.Add(this.scalesFontSizeComboBox);
+      this.groupBox3.Controls.Add(this.label10);
+      this.groupBox3.Controls.Add(this.axisFontSizeComboBox);
+      this.groupBox3.Controls.Add(this.titleFontSizeComboBox);
+      this.groupBox3.Location = new System.Drawing.Point(12, 242);
+      this.groupBox3.Name = "groupBox3";
+      this.groupBox3.Size = new System.Drawing.Size(258, 131);
+      this.groupBox3.TabIndex = 4;
+      this.groupBox3.TabStop = false;
+      this.groupBox3.Text = "Font Size";
+      // 
+      // label18
+      // 
+      this.label18.AutoSize = true;
+      this.label18.Location = new System.Drawing.Point(144, 105);
+      this.label18.Name = "label18";
+      this.label18.Size = new System.Drawing.Size(16, 13);
+      this.label18.TabIndex = 0;
+      this.label18.Text = "pt";
+      // 
+      // label12
+      // 
+      this.label12.AutoSize = true;
+      this.label12.Location = new System.Drawing.Point(144, 78);
+      this.label12.Name = "label12";
+      this.label12.Size = new System.Drawing.Size(16, 13);
+      this.label12.TabIndex = 0;
+      this.label12.Text = "pt";
+      // 
+      // label11
+      // 
+      this.label11.AutoSize = true;
+      this.label11.Location = new System.Drawing.Point(144, 51);
+      this.label11.Name = "label11";
+      this.label11.Size = new System.Drawing.Size(16, 13);
+      this.label11.TabIndex = 0;
+      this.label11.Text = "pt";
+      // 
+      // label7
+      // 
+      this.label7.AutoSize = true;
+      this.label7.Location = new System.Drawing.Point(144, 22);
+      this.label7.Name = "label7";
+      this.label7.Size = new System.Drawing.Size(16, 13);
+      this.label7.TabIndex = 0;
+      this.label7.Text = "pt";
+      // 
+      // legendFontSizeComboBox
+      // 
+      this.legendFontSizeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.legendFontSizeComboBox.FormattingEnabled = true;
+      this.legendFontSizeComboBox.Items.AddRange(new object[] {
+            "4",
+            "5",
+            "6",
+            "7",
+            "8",
+            "9",
+            "10",
+            "11",
+            "12",
+            "14",
+            "16",
+            "18",
+            "24",
+            "36",
+            "72"});
+      this.legendFontSizeComboBox.Location = new System.Drawing.Point(54, 100);
+      this.legendFontSizeComboBox.Name = "legendFontSizeComboBox";
+      this.legendFontSizeComboBox.Size = new System.Drawing.Size(84, 21);
+      this.legendFontSizeComboBox.TabIndex = 5;
+      this.legendFontSizeComboBox.TextChanged += new System.EventHandler(this.legendFontSizeComboBox_TextChanged);
+      this.legendFontSizeComboBox.Validating += new System.ComponentModel.CancelEventHandler(this.numericComboBox_Validating);
+      // 
+      // label17
+      // 
+      this.label17.AutoSize = true;
+      this.label17.Location = new System.Drawing.Point(6, 105);
+      this.label17.Name = "label17";
+      this.label17.Size = new System.Drawing.Size(46, 13);
+      this.label17.TabIndex = 4;
+      this.label17.Text = "Legend:";
+      // 
+      // titleFontSizeComboBox
+      // 
+      this.titleFontSizeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.titleFontSizeComboBox.FormattingEnabled = true;
+      this.titleFontSizeComboBox.Items.AddRange(new object[] {
+            "6",
+            "8",
+            "10",
+            "11",
+            "12",
+            "14",
+            "16",
+            "18",
+            "24",
+            "36",
+            "72"});
+      this.titleFontSizeComboBox.Location = new System.Drawing.Point(54, 19);
+      this.titleFontSizeComboBox.Name = "titleFontSizeComboBox";
+      this.titleFontSizeComboBox.Size = new System.Drawing.Size(84, 21);
+      this.titleFontSizeComboBox.TabIndex = 1;
+      this.titleFontSizeComboBox.TextChanged += new System.EventHandler(this.titleFontSizeComboBox_TextChanged);
+      this.titleFontSizeComboBox.Validating += new System.ComponentModel.CancelEventHandler(this.numericComboBox_Validating);
+      // 
+      // label16
+      // 
+      this.label16.AutoSize = true;
+      this.label16.Location = new System.Drawing.Point(10, 438);
+      this.label16.Name = "label16";
+      this.label16.Size = new System.Drawing.Size(41, 13);
+      this.label16.TabIndex = 10;
+      this.label16.Text = "Height:";
+      // 
+      // heightNumericUD
+      // 
+      this.heightNumericUD.DecimalPlaces = 2;
+      this.heightNumericUD.Increment = new decimal(new int[] {
+            5,
+            0,
+            0,
+            65536});
+      this.heightNumericUD.Location = new System.Drawing.Point(76, 436);
+      this.heightNumericUD.Maximum = new decimal(new int[] {
+            1000,
+            0,
+            0,
+            0});
+      this.heightNumericUD.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            131072});
+      this.heightNumericUD.Name = "heightNumericUD";
+      this.heightNumericUD.Size = new System.Drawing.Size(75, 20);
+      this.heightNumericUD.TabIndex = 11;
+      this.heightNumericUD.Value = new decimal(new int[] {
+            8,
+            0,
+            0,
+            0});
+      this.heightNumericUD.ValueChanged += new System.EventHandler(this.heightNumericUD_ValueChanged);
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.IsSplitterFixed = true;
+      this.splitContainer.Location = new System.Drawing.Point(0, 1);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.chartAreaComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.togglePreviewCheckBox);
+      this.splitContainer.Panel1.Controls.Add(this.titleTextBox);
+      this.splitContainer.Panel1.Controls.Add(this.groupBox3);
+      this.splitContainer.Panel1.Controls.Add(this.label6);
+      this.splitContainer.Panel1.Controls.Add(this.groupBox2);
+      this.splitContainer.Panel1.Controls.Add(this.groupBox1);
+      this.splitContainer.Panel1.Controls.Add(this.label16);
+      this.splitContainer.Panel1.Controls.Add(this.heightNumericUD);
+      this.splitContainer.Panel1.Controls.Add(this.widthNumericUD);
+      this.splitContainer.Panel1.Controls.Add(this.label5);
+      this.splitContainer.Panel1.Controls.Add(this.lengthUnitComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.resolutionUnitComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.resolutionComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.label8);
+      this.splitContainer.Panel1.Controls.Add(this.label2);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.previewPictureBox);
+      this.splitContainer.Panel2.Controls.Add(this.label13);
+      this.splitContainer.Panel2.Controls.Add(this.previewZoomLabel);
+      this.splitContainer.Size = new System.Drawing.Size(793, 478);
+      this.splitContainer.SplitterDistance = 300;
+      this.splitContainer.SplitterWidth = 1;
+      this.splitContainer.TabIndex = 15;
+      // 
+      // chartAreaComboBox
+      // 
+      this.chartAreaComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.chartAreaComboBox.FormattingEnabled = true;
+      this.chartAreaComboBox.Location = new System.Drawing.Point(76, 37);
+      this.chartAreaComboBox.Name = "chartAreaComboBox";
+      this.chartAreaComboBox.Size = new System.Drawing.Size(189, 21);
+      this.chartAreaComboBox.TabIndex = 17;
+      this.chartAreaComboBox.SelectedIndexChanged += new System.EventHandler(this.chartAreaComboBox_SelectedIndexChanged);
+      // 
+      // togglePreviewCheckBox
+      // 
+      this.togglePreviewCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)));
+      this.togglePreviewCheckBox.Appearance = System.Windows.Forms.Appearance.Button;
+      this.togglePreviewCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+      this.togglePreviewCheckBox.Location = new System.Drawing.Point(277, 3);
+      this.togglePreviewCheckBox.Name = "togglePreviewCheckBox";
+      this.togglePreviewCheckBox.Size = new System.Drawing.Size(20, 472);
+      this.togglePreviewCheckBox.TabIndex = 16;
+      this.togglePreviewCheckBox.Text = ">";
+      this.togglePreviewCheckBox.UseVisualStyleBackColor = true;
+      this.togglePreviewCheckBox.CheckedChanged += new System.EventHandler(this.togglePreviewCheckBox_CheckedChanged);
+      // 
+      // lengthUnitComboBox
+      // 
+      this.lengthUnitComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.lengthUnitComboBox.FormattingEnabled = true;
+      this.lengthUnitComboBox.Location = new System.Drawing.Point(157, 422);
+      this.lengthUnitComboBox.Name = "lengthUnitComboBox";
+      this.lengthUnitComboBox.Size = new System.Drawing.Size(108, 21);
+      this.lengthUnitComboBox.TabIndex = 6;
+      this.lengthUnitComboBox.SelectedIndexChanged += new System.EventHandler(this.lengthUnitComboBox_SelectedIndexChanged);
+      // 
+      // resolutionUnitComboBox
+      // 
+      this.resolutionUnitComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.resolutionUnitComboBox.FormattingEnabled = true;
+      this.resolutionUnitComboBox.Location = new System.Drawing.Point(157, 383);
+      this.resolutionUnitComboBox.Name = "resolutionUnitComboBox";
+      this.resolutionUnitComboBox.Size = new System.Drawing.Size(108, 21);
+      this.resolutionUnitComboBox.TabIndex = 6;
+      this.resolutionUnitComboBox.SelectedIndexChanged += new System.EventHandler(this.resolutionUnitComboBox_SelectedIndexChanged);
+      // 
+      // label8
+      // 
+      this.label8.AutoSize = true;
+      this.label8.Location = new System.Drawing.Point(10, 40);
+      this.label8.Name = "label8";
+      this.label8.Size = new System.Drawing.Size(60, 13);
+      this.label8.TabIndex = 0;
+      this.label8.Text = "Chart Area:";
+      // 
+      // previewPictureBox
+      // 
+      this.previewPictureBox.Location = new System.Drawing.Point(0, 3);
+      this.previewPictureBox.Name = "previewPictureBox";
+      this.previewPictureBox.Size = new System.Drawing.Size(492, 453);
+      this.previewPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
+      this.previewPictureBox.TabIndex = 0;
+      this.previewPictureBox.TabStop = false;
+      // 
+      // label13
+      // 
+      this.label13.AutoSize = true;
+      this.label13.Location = new System.Drawing.Point(3, 459);
+      this.label13.Name = "label13";
+      this.label13.Size = new System.Drawing.Size(37, 13);
+      this.label13.TabIndex = 10;
+      this.label13.Text = "Zoom:";
+      // 
+      // previewZoomLabel
+      // 
+      this.previewZoomLabel.AutoSize = true;
+      this.previewZoomLabel.Location = new System.Drawing.Point(46, 459);
+      this.previewZoomLabel.Name = "previewZoomLabel";
+      this.previewZoomLabel.Size = new System.Drawing.Size(33, 13);
+      this.previewZoomLabel.TabIndex = 10;
+      this.previewZoomLabel.Text = "100%";
+      // 
+      // saveFileDialog
+      // 
+      this.saveFileDialog.Filter = "Bitmap (*.bmp)|*.bmp|JPEG (*.jpg)|*.jpg|EMF (*.emf)|*.emf|PNG (*.png)|*.png|GIF (" +
+          "*.gif)|*.gif|TIFF (*.tif)|*.tif\"";
+      this.saveFileDialog.FilterIndex = 2;
+      // 
+      // ImageExportDialog
+      // 
+      this.AcceptButton = this.okButton;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(794, 522);
+      this.ControlBox = false;
+      this.Controls.Add(this.splitContainer);
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+      this.Name = "ImageExportDialog";
+      this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
+      this.Text = "Export Image";
+      this.TopMost = true;
+      ((System.ComponentModel.ISupportInitialize)(this.widthNumericUD)).EndInit();
+      this.groupBox1.ResumeLayout(false);
+      this.groupBox1.PerformLayout();
+      this.groupBox2.ResumeLayout(false);
+      this.groupBox2.PerformLayout();
+      this.groupBox3.ResumeLayout(false);
+      this.groupBox3.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.heightNumericUD)).EndInit();
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.Panel2.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox titleTextBox;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Button okButton;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.TextBox secondaryXTextBox;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.TextBox secondaryYTextBox;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.ComboBox resolutionComboBox;
+    private System.Windows.Forms.NumericUpDown widthNumericUD;
+    private System.Windows.Forms.Label label5;
+    private System.Windows.Forms.Label label6;
+    private System.Windows.Forms.ComboBox axisFontSizeComboBox;
+    private System.Windows.Forms.ComboBox scalesFontSizeComboBox;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.Label label9;
+    private System.Windows.Forms.Label label10;
+    private System.Windows.Forms.GroupBox groupBox1;
+    private System.Windows.Forms.GroupBox groupBox2;
+    private System.Windows.Forms.TextBox primaryXTextBox;
+    private System.Windows.Forms.TextBox primaryYTextBox;
+    private System.Windows.Forms.Label label14;
+    private System.Windows.Forms.Label label15;
+    private System.Windows.Forms.GroupBox groupBox3;
+    private System.Windows.Forms.Label label16;
+    private System.Windows.Forms.NumericUpDown heightNumericUD;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.CheckBox togglePreviewCheckBox;
+    private System.Windows.Forms.PictureBox previewPictureBox;
+    private System.Windows.Forms.Label label12;
+    private System.Windows.Forms.Label label11;
+    private System.Windows.Forms.Label label7;
+    private System.Windows.Forms.ComboBox titleFontSizeComboBox;
+    private System.Windows.Forms.ComboBox lengthUnitComboBox;
+    private System.Windows.Forms.ComboBox resolutionUnitComboBox;
+    private System.Windows.Forms.ComboBox chartAreaComboBox;
+    private System.Windows.Forms.Label label8;
+    private System.Windows.Forms.SaveFileDialog saveFileDialog;
+    private System.Windows.Forms.Label label13;
+    private System.Windows.Forms.Label previewZoomLabel;
+    private System.Windows.Forms.Label label18;
+    private System.Windows.Forms.ComboBox legendFontSizeComboBox;
+    private System.Windows.Forms.Label label17;
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.cs	(revision 6647)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.cs	(revision 6647)
@@ -0,0 +1,379 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.ComponentModel;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+
+namespace HeuristicLab.Visualization.ChartControlsExtensions {
+  public sealed partial class ImageExportDialog : Form {
+    private const float CMPERINCH = 2.54f;
+    private static readonly string DPI = "dpi", DPCM = "dpcm", INCH = "inch", CM = "cm";
+    private Chart originalChart, workingChart;
+    private bool SuppressEvents { get; set; }
+
+    /// <summary>
+    /// Initializes a new ImageExportDialog.
+    /// </summary>
+    /// <remarks>
+    /// Throws an ArgumentNullException if <paramref name="chart"/> is null.
+    /// </remarks>
+    /// <param name="chart">The chart for which the export should be generated.</param>
+    public ImageExportDialog(Chart chart) {
+      if (chart == null) throw new ArgumentNullException("chart");
+      this.originalChart = chart;
+      InitializeComponent();
+      #region Custom Initialization
+      SuppressEvents = true;
+      try {
+        resolutionUnitComboBox.Items.Add(DPI);
+        resolutionUnitComboBox.Items.Add(DPCM);
+        lengthUnitComboBox.Items.Add(INCH);
+        lengthUnitComboBox.Items.Add(CM);
+        resolutionUnitComboBox.SelectedIndex = 0;
+        if (System.Globalization.RegionInfo.CurrentRegion.IsMetric)
+          lengthUnitComboBox.SelectedIndex = 1;
+        else lengthUnitComboBox.SelectedIndex = 0;
+
+        titleFontSizeComboBox.Text = "12";
+        axisFontSizeComboBox.Text = "8";
+        scalesFontSizeComboBox.Text = "6";
+        legendFontSizeComboBox.Text = "6";
+        resolutionComboBox.Text = "300";
+        SuppressEvents = false;
+        splitContainer.Panel2Collapsed = true;
+        Width = 305;
+        Height = 550;
+      } finally { SuppressEvents = false; }
+      #endregion
+    }
+
+    private void UpdateFields() {
+      ChartArea area = GetCurrentChartArea();
+
+      try {
+        SuppressEvents = true;
+
+        if (workingChart.Titles.Count == 0) titleFontSizeComboBox.Text = "12";
+        else {
+          titleTextBox.Text = workingChart.Titles[0].Text;
+          titleFontSizeComboBox.Text = workingChart.Titles[0].Font.SizeInPoints.ToString();
+        }
+
+        primaryXTextBox.Text = area.AxisX.Title;
+        primaryYTextBox.Text = area.AxisY.Title;
+        secondaryXTextBox.Text = area.AxisX2.Title;
+        secondaryYTextBox.Text = area.AxisY2.Title;
+
+        axisFontSizeComboBox.Text = area.AxisX.TitleFont.SizeInPoints.ToString();
+        scalesFontSizeComboBox.Text = area.AxisX.LabelStyle.Font.SizeInPoints.ToString();
+        if (workingChart.Legends.Count == 0) legendFontSizeComboBox.Text = "8";
+        else legendFontSizeComboBox.Text = workingChart.Legends[0].Font.SizeInPoints.ToString();
+      } finally {
+        SuppressEvents = false;
+      }
+    }
+
+    private ChartArea GetCurrentChartArea() {
+      return workingChart.ChartAreas[chartAreaComboBox.Text];
+    }
+
+    private void UpdatePreview() {
+      float dpi;
+      float width;
+      float height;
+      GetImageParameters(out dpi, out width, out height);
+
+      if (previewPictureBox.Image != null) {
+        previewPictureBox.Image.Dispose();
+        previewPictureBox.Image = null;
+      }
+
+      int previewWidth, previewHeight;
+      if (width / height >= 1.0) {
+        previewWidth = previewPictureBox.Width;
+        previewHeight = (int)Math.Round(height / width * previewWidth);
+      } else {
+        previewHeight = previewPictureBox.Height;
+        previewWidth = (int)Math.Round(width / height * previewHeight);
+      }
+
+      float scaleFactor = (float)Math.Min(previewWidth / width, previewHeight / height);
+      if (scaleFactor >= 1) {
+        previewZoomLabel.Text = "100%";
+        previewWidth = (int)Math.Round(width);
+        previewHeight = (int)Math.Round(height);
+      } else previewZoomLabel.Text = (scaleFactor * 100).ToString("0") + "%";
+
+      Bitmap image = new Bitmap(previewWidth, previewHeight);
+      image.SetResolution(dpi, dpi);
+      using (Graphics graphics = Graphics.FromImage(image)) {
+        if (scaleFactor < 1) graphics.ScaleTransform(scaleFactor, scaleFactor);
+        workingChart.Printing.PrintPaint(graphics, new Rectangle(0, 0, (int)Math.Round(width), (int)Math.Round(height)));
+      }
+      previewPictureBox.Image = image;
+    }
+
+    private void GetImageParameters(out float dpi, out float width, out float height) {
+      dpi = float.Parse(resolutionComboBox.Text);
+      if (resolutionUnitComboBox.Text == DPCM) dpi *= CMPERINCH;
+      width = (float)widthNumericUD.Value;
+      height = (float)heightNumericUD.Value;
+      if (lengthUnitComboBox.Text == CM) {
+        width /= CMPERINCH; height /= CMPERINCH;
+      }
+      width *= dpi; height *= dpi;
+    }
+
+    protected override void OnShown(EventArgs e) {
+      #region Create copy of chart
+      var prevContent = originalChart.Serializer.Content;
+      var prevFormat = originalChart.Serializer.Format;
+      originalChart.Serializer.Content = SerializationContents.Default;
+      originalChart.Serializer.Format = SerializationFormat.Binary;
+      MemoryStream ms = new MemoryStream();
+      originalChart.Serializer.Save(ms);
+
+      ms.Seek(0, SeekOrigin.Begin);
+      workingChart = new EnhancedChart();
+      workingChart.Serializer.Format = originalChart.Serializer.Format;
+      workingChart.Serializer.Load(ms);
+      ms.Close();
+
+      originalChart.Serializer.Content = prevContent;
+      originalChart.Serializer.Format = prevFormat;
+      #endregion
+
+      chartAreaComboBox.Items.Clear();
+      foreach (ChartArea area in originalChart.ChartAreas) {
+        chartAreaComboBox.Items.Add(area.Name);
+      }
+      chartAreaComboBox.SelectedIndex = 0;
+      base.OnShown(e);
+
+      if (togglePreviewCheckBox.Checked) UpdatePreview();
+    }
+
+    private void togglePreviewCheckBox_CheckedChanged(object sender, EventArgs e) {
+      splitContainer.Panel2Collapsed = !togglePreviewCheckBox.Checked;
+      togglePreviewCheckBox.Text = togglePreviewCheckBox.Checked ? "<" : ">";
+      if (splitContainer.Panel2Collapsed)
+        Width = cancelButton.Right + cancelButton.Margin.Right + Margin.Right + 10;
+      else
+        Width = splitContainer.Right + splitContainer.Margin.Right + Margin.Right;
+      if (togglePreviewCheckBox.Checked) UpdatePreview();
+    }
+
+    private void chartAreaComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (chartAreaComboBox.SelectedIndex >= 0)
+        UpdateFields();
+    }
+
+    private void titleTextBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        if (workingChart.Titles.Count > 0) {
+          workingChart.Titles[0].Text = titleTextBox.Text;
+        } else {
+          Title t = new Title(titleTextBox.Text);
+          t.Font = ChangeFontSizePt(t.Font, float.Parse(titleFontSizeComboBox.Text));
+          workingChart.Titles.Add(t);
+        }
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void primaryXTextBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        ChartArea area = GetCurrentChartArea();
+        area.AxisX.Title = primaryXTextBox.Text;
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void primaryYTextBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        ChartArea area = GetCurrentChartArea();
+        area.AxisY.Title = primaryYTextBox.Text;
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void secondaryXTextBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        ChartArea area = GetCurrentChartArea();
+        area.AxisX2.Title = secondaryXTextBox.Text;
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void secondaryYTextBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        ChartArea area = GetCurrentChartArea();
+        area.AxisY2.Title = secondaryYTextBox.Text;
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void widthNumericUD_ValueChanged(object sender, EventArgs e) {
+      if (togglePreviewCheckBox.Checked) UpdatePreview();
+    }
+
+    private void heightNumericUD_ValueChanged(object sender, EventArgs e) {
+      if (togglePreviewCheckBox.Checked) UpdatePreview();
+    }
+
+    private void titleFontSizeComboBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        float fontSize;
+        if (float.TryParse(titleFontSizeComboBox.Text, out fontSize)) {
+          if (workingChart.Titles.Count > 0) {
+            workingChart.Titles[0].Font = ChangeFontSizePt(workingChart.Titles[0].Font, fontSize);
+            if (togglePreviewCheckBox.Checked) UpdatePreview();
+          }
+        }
+      }
+    }
+
+    private void axisFontSizeComboBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        float fontSize;
+        if (float.TryParse(axisFontSizeComboBox.Text, out fontSize)) {
+          ChartArea area = GetCurrentChartArea();
+          foreach (Axis a in area.Axes) {
+            a.TitleFont = ChangeFontSizePt(a.TitleFont, fontSize);
+          }
+        }
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void scalesFontSizeComboBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        float fontSize;
+        if (float.TryParse(scalesFontSizeComboBox.Text, out fontSize)) {
+          ChartArea area = GetCurrentChartArea();
+          foreach (Axis a in area.Axes) {
+            a.LabelStyle.Font = ChangeFontSizePt(a.LabelStyle.Font, fontSize);
+          }
+        }
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void legendFontSizeComboBox_TextChanged(object sender, EventArgs e) {
+      if (!SuppressEvents) {
+        float fontSize;
+        if (float.TryParse(legendFontSizeComboBox.Text, out fontSize)) {
+          foreach (Legend l in workingChart.Legends) {
+            l.Font = ChangeFontSizePt(l.Font, fontSize);
+          }
+        }
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void numericComboBox_Validating(object sender, CancelEventArgs e) {
+      if (!(sender is ComboBox)) return;
+      float number;
+      e.Cancel = !float.TryParse((sender as ComboBox).Text, out number);
+    }
+
+    private void resolutionComboBox_TextChanged(object sender, EventArgs e) {
+      float resolution;
+      if (float.TryParse(resolutionComboBox.Text, out resolution)) {
+        if (togglePreviewCheckBox.Checked) UpdatePreview();
+      }
+    }
+
+    private void resolutionComboBox_Validating(object sender, CancelEventArgs e) {
+      float resolution;
+      e.Cancel = !float.TryParse(resolutionComboBox.Text, out resolution);
+    }
+
+    private void resolutionUnitComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (togglePreviewCheckBox.Checked) UpdatePreview();
+    }
+
+    private void lengthUnitComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (togglePreviewCheckBox.Checked) UpdatePreview();
+    }
+
+    private void okButton_Click(object sender, EventArgs e) {
+      float dpi;
+      float width;
+      float height;
+      GetImageParameters(out dpi, out width, out height);
+
+      Bitmap image = new Bitmap((int)Math.Round(width), (int)Math.Round(height));
+      image.SetResolution(dpi, dpi);
+      using (Graphics graphics = Graphics.FromImage(image)) {
+        workingChart.Printing.PrintPaint(graphics, new Rectangle(0, 0, image.Width, image.Height));
+      }
+
+      if (titleTextBox.Text.Trim() != String.Empty) saveFileDialog.FileName = titleTextBox.Text.Trim();
+      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
+        ImageFormat format = ImageFormat.Bmp;
+        string filename = saveFileDialog.FileName.ToLower();
+        if (filename.EndsWith("jpg")) {
+          format = ImageFormat.Jpeg;
+        } else if (filename.EndsWith("emf")) {
+          format = ImageFormat.Emf;
+        } else if (filename.EndsWith("gif")) {
+          format = ImageFormat.Gif;
+        } else if (filename.EndsWith("png")) {
+          format = ImageFormat.Png;
+        } else if (filename.EndsWith("tif")) {
+          format = ImageFormat.Tiff;
+        }
+        image.Save(saveFileDialog.FileName, format);
+      }
+
+      image.Dispose();
+
+      Cleanup();
+    }
+
+    private void cancelButton_Click(object sender, EventArgs e) {
+      Cleanup();
+    }
+
+    private void Cleanup() {
+      if (previewPictureBox.Image != null) previewPictureBox.Image.Dispose();
+      previewPictureBox.Image = null;
+      workingChart = null;
+    }
+
+    private static Font ChangeFontSizePt(Font font, float fontSize) {
+      if (font != null) {
+        float currentSize = font.Size;
+        if (currentSize != fontSize) {
+          font = new Font(font.Name, fontSize, font.Style, GraphicsUnit.Point, font.GdiCharSet, font.GdiVerticalFont);
+        }
+      }
+      return font;
+    }
+
+  }
+}
Index: /branches/GP.Grammar.Editor/HeuristicLab/3.3/Files.txt
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab/3.3/Files.txt	(revision 6646)
+++ /branches/GP.Grammar.Editor/HeuristicLab/3.3/Files.txt	(revision 6647)
@@ -81,4 +81,5 @@
 HeuristicLab.Problems.OneMax.Views\3.3:HeuristicLab.Problems.OneMax.Views-3.3.dll
 HeuristicLab.Problems.QuadraticAssignment\3.3:HeuristicLab.Problems.QuadraticAssignment-3.3.dll
+HeuristicLab.Problems.QuadraticAssignment.Algorithms\3.3:HeuristicLab.Problems.QuadraticAssignment.Algorithms-3.3.dll
 HeuristicLab.Problems.QuadraticAssignment.Views\3.3:HeuristicLab.Problems.QuadraticAssignment.Views-3.3.dll
 HeuristicLab.Problems.TestFunctions\3.3:HeuristicLab.Problems.TestFunctions-3.3.dll
