Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/ExpertSystemView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/ExpertSystemView.Designer.cs	(revision 13560)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/ExpertSystemView.Designer.cs	(revision 13561)
@@ -34,4 +34,9 @@
     /// </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();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
       this.evaluationsLimitabel = new System.Windows.Forms.Label();
       this.maxEvaluationsTextBox = new System.Windows.Forms.TextBox();
@@ -40,4 +45,5 @@
       this.problemViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
       this.algorithmTabPage = new System.Windows.Forms.TabPage();
+      this.algorithmStartButton = new System.Windows.Forms.Button();
       this.algorithmViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
       this.algorithmSuggestionLabel = new System.Windows.Forms.Label();
@@ -48,12 +54,15 @@
       this.kbViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
       this.problemInstancesTabPage = new System.Windows.Forms.TabPage();
+      this.label1 = new System.Windows.Forms.Label();
+      this.projectionComboBox = new System.Windows.Forms.ComboBox();
+      this.problemInstancesTabControl = new System.Windows.Forms.TabControl();
+      this.instancesTabPage = new System.Windows.Forms.TabPage();
       this.problemInstancesView = new HeuristicLab.MainForm.WindowsForms.ViewHost();
-      this.instancesDropPanel = new System.Windows.Forms.Panel();
-      this.dragFLAHereLabel = new System.Windows.Forms.Label();
+      this.mapTabPage = new System.Windows.Forms.TabPage();
+      this.instanceMapChart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
       this.refreshMapButton = new System.Windows.Forms.Button();
       this.progressPanel = new System.Windows.Forms.Panel();
       this.okbDownloadButton = new System.Windows.Forms.Button();
       this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
-      this.algorithmStartButton = new System.Windows.Forms.Button();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       this.tabControl.SuspendLayout();
@@ -63,5 +72,8 @@
       this.okbTabPage.SuspendLayout();
       this.problemInstancesTabPage.SuspendLayout();
-      this.instancesDropPanel.SuspendLayout();
+      this.problemInstancesTabControl.SuspendLayout();
+      this.instancesTabPage.SuspendLayout();
+      this.mapTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.instanceMapChart)).BeginInit();
       this.SuspendLayout();
       // 
@@ -88,5 +100,5 @@
       // maxEvaluationsTextBox
       // 
-      this.maxEvaluationsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+      this.maxEvaluationsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.maxEvaluationsTextBox.Location = new System.Drawing.Point(75, 26);
@@ -94,11 +106,11 @@
       this.maxEvaluationsTextBox.Size = new System.Drawing.Size(449, 20);
       this.maxEvaluationsTextBox.TabIndex = 6;
-      this.maxEvaluationsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.maxEvaluationsTextBox_Validating);
+      this.maxEvaluationsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.MaxEvaluationsTextBoxOnValidating);
       // 
       // tabControl
       // 
       this.tabControl.AllowDrop = true;
-      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.tabControl.Controls.Add(this.problemTabPage);
@@ -153,8 +165,19 @@
       this.algorithmTabPage.UseVisualStyleBackColor = true;
       // 
+      // algorithmStartButton
+      // 
+      this.algorithmStartButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmStartButton.Location = new System.Drawing.Point(506, 5);
+      this.algorithmStartButton.Name = "algorithmStartButton";
+      this.algorithmStartButton.Size = new System.Drawing.Size(26, 23);
+      this.algorithmStartButton.TabIndex = 3;
+      this.algorithmStartButton.Text = "Start";
+      this.algorithmStartButton.UseVisualStyleBackColor = true;
+      this.algorithmStartButton.Click += new System.EventHandler(this.AlgorithmStartButtonOnClick);
+      // 
       // algorithmViewHost
       // 
-      this.algorithmViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
+      this.algorithmViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.algorithmViewHost.Caption = "View";
@@ -180,5 +203,5 @@
       // suggestedInstancesComboBox
       // 
-      this.suggestedInstancesComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+      this.suggestedInstancesComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.suggestedInstancesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
@@ -238,6 +261,7 @@
       // problemInstancesTabPage
       // 
-      this.problemInstancesTabPage.Controls.Add(this.problemInstancesView);
-      this.problemInstancesTabPage.Controls.Add(this.instancesDropPanel);
+      this.problemInstancesTabPage.Controls.Add(this.label1);
+      this.problemInstancesTabPage.Controls.Add(this.projectionComboBox);
+      this.problemInstancesTabPage.Controls.Add(this.problemInstancesTabControl);
       this.problemInstancesTabPage.Controls.Add(this.refreshMapButton);
       this.problemInstancesTabPage.Location = new System.Drawing.Point(4, 22);
@@ -249,46 +273,103 @@
       this.problemInstancesTabPage.UseVisualStyleBackColor = true;
       // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(35, 11);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(57, 13);
+      this.label1.TabIndex = 6;
+      this.label1.Text = "Projection:";
+      // 
+      // projectionComboBox
+      // 
+      this.projectionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.projectionComboBox.FormattingEnabled = true;
+      this.projectionComboBox.Location = new System.Drawing.Point(98, 8);
+      this.projectionComboBox.Name = "projectionComboBox";
+      this.projectionComboBox.Size = new System.Drawing.Size(158, 21);
+      this.projectionComboBox.TabIndex = 5;
+      this.projectionComboBox.SelectedIndexChanged += new System.EventHandler(this.ProjectionComboBoxOnSelectedIndexChanged);
+      // 
+      // problemInstancesTabControl
+      // 
+      this.problemInstancesTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.problemInstancesTabControl.Controls.Add(this.instancesTabPage);
+      this.problemInstancesTabControl.Controls.Add(this.mapTabPage);
+      this.problemInstancesTabControl.Location = new System.Drawing.Point(3, 35);
+      this.problemInstancesTabControl.Name = "problemInstancesTabControl";
+      this.problemInstancesTabControl.SelectedIndex = 0;
+      this.problemInstancesTabControl.Size = new System.Drawing.Size(532, 268);
+      this.problemInstancesTabControl.TabIndex = 4;
+      // 
+      // instancesTabPage
+      // 
+      this.instancesTabPage.Controls.Add(this.problemInstancesView);
+      this.instancesTabPage.Location = new System.Drawing.Point(4, 22);
+      this.instancesTabPage.Name = "instancesTabPage";
+      this.instancesTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.instancesTabPage.Size = new System.Drawing.Size(524, 242);
+      this.instancesTabPage.TabIndex = 0;
+      this.instancesTabPage.Text = "Instances";
+      this.instancesTabPage.UseVisualStyleBackColor = true;
+      // 
       // problemInstancesView
       // 
-      this.problemInstancesView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
       this.problemInstancesView.Caption = "View";
       this.problemInstancesView.Content = null;
+      this.problemInstancesView.Dock = System.Windows.Forms.DockStyle.Fill;
       this.problemInstancesView.Enabled = false;
-      this.problemInstancesView.Location = new System.Drawing.Point(3, 34);
+      this.problemInstancesView.Location = new System.Drawing.Point(3, 3);
       this.problemInstancesView.Name = "problemInstancesView";
       this.problemInstancesView.ReadOnly = false;
-      this.problemInstancesView.Size = new System.Drawing.Size(532, 269);
-      this.problemInstancesView.TabIndex = 3;
+      this.problemInstancesView.Size = new System.Drawing.Size(518, 236);
+      this.problemInstancesView.TabIndex = 0;
       this.problemInstancesView.ViewsLabelVisible = true;
       this.problemInstancesView.ViewType = null;
       // 
-      // instancesDropPanel
-      // 
-      this.instancesDropPanel.AllowDrop = true;
-      this.instancesDropPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.instancesDropPanel.BackColor = System.Drawing.Color.LightYellow;
-      this.instancesDropPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
-      this.instancesDropPanel.Controls.Add(this.dragFLAHereLabel);
-      this.instancesDropPanel.Location = new System.Drawing.Point(35, 7);
-      this.instancesDropPanel.Name = "instancesDropPanel";
-      this.instancesDropPanel.Size = new System.Drawing.Size(500, 21);
-      this.instancesDropPanel.TabIndex = 2;
-      this.instancesDropPanel.DragDrop += new System.Windows.Forms.DragEventHandler(this.instancesDropPanel_DragDrop);
-      this.instancesDropPanel.DragEnter += new System.Windows.Forms.DragEventHandler(this.instancesDropPanel_DragEnter);
-      this.instancesDropPanel.DragOver += new System.Windows.Forms.DragEventHandler(this.instancesDropPanel_DragOver);
-      // 
-      // dragFLAHereLabel
-      // 
-      this.dragFLAHereLabel.Anchor = System.Windows.Forms.AnchorStyles.None;
-      this.dragFLAHereLabel.AutoSize = true;
-      this.dragFLAHereLabel.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
-      this.dragFLAHereLabel.Location = new System.Drawing.Point(155, 3);
-      this.dragFLAHereLabel.Name = "dragFLAHereLabel";
-      this.dragFLAHereLabel.Size = new System.Drawing.Size(175, 13);
-      this.dragFLAHereLabel.TabIndex = 0;
-      this.dragFLAHereLabel.Text = "Drag and drop runs with FLA here...";
+      // mapTabPage
+      // 
+      this.mapTabPage.Controls.Add(this.instanceMapChart);
+      this.mapTabPage.Location = new System.Drawing.Point(4, 22);
+      this.mapTabPage.Name = "mapTabPage";
+      this.mapTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.mapTabPage.Size = new System.Drawing.Size(524, 242);
+      this.mapTabPage.TabIndex = 1;
+      this.mapTabPage.Text = "Map";
+      this.mapTabPage.UseVisualStyleBackColor = true;
+      // 
+      // instanceMapChart
+      // 
+      chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.LightGray;
+      chartArea1.AxisX.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.LightGray;
+      chartArea1.AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea1.Name = "Default";
+      this.instanceMapChart.ChartAreas.Add(chartArea1);
+      this.instanceMapChart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Enabled = false;
+      legend1.Name = "Legend";
+      this.instanceMapChart.Legends.Add(legend1);
+      this.instanceMapChart.Location = new System.Drawing.Point(3, 3);
+      this.instanceMapChart.Name = "instanceMapChart";
+      series1.ChartArea = "Default";
+      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
+      series1.Legend = "Legend";
+      series1.MarkerSize = 10;
+      series1.Name = "InstancesSeries";
+      series2.ChartArea = "Default";
+      series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
+      series2.Legend = "Legend";
+      series2.MarkerColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
+      series2.MarkerSize = 15;
+      series2.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Cross;
+      series2.Name = "CurrentInstanceSeries";
+      this.instanceMapChart.Series.Add(series1);
+      this.instanceMapChart.Series.Add(series2);
+      this.instanceMapChart.Size = new System.Drawing.Size(518, 236);
+      this.instanceMapChart.TabIndex = 0;
       // 
       // refreshMapButton
@@ -300,10 +381,10 @@
       this.refreshMapButton.Text = "Refresh";
       this.refreshMapButton.UseVisualStyleBackColor = true;
-      this.refreshMapButton.Click += new System.EventHandler(this.refreshMapButton_Click);
+      this.refreshMapButton.Click += new System.EventHandler(this.RefreshMapButtonOnClick);
       // 
       // progressPanel
       // 
-      this.progressPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
+      this.progressPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.progressPanel.Location = new System.Drawing.Point(0, 81);
@@ -315,5 +396,5 @@
       // okbDownloadButton
       // 
-      this.okbDownloadButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+      this.okbDownloadButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.okbDownloadButton.Location = new System.Drawing.Point(6, 52);
@@ -323,5 +404,5 @@
       this.okbDownloadButton.Text = "Download from OKB";
       this.okbDownloadButton.UseVisualStyleBackColor = true;
-      this.okbDownloadButton.Click += new System.EventHandler(this.okbDownloadButton_Click);
+      this.okbDownloadButton.Click += new System.EventHandler(this.OkbDownloadButtonOnClick);
       // 
       // openFileDialog
@@ -331,14 +412,4 @@
       this.openFileDialog.Filter = "HeuristicLab Files|*.hl|All Files|*.*";
       this.openFileDialog.Title = "Open Optimizer";
-      // 
-      // algorithmStartButton
-      // 
-      this.algorithmStartButton.Location = new System.Drawing.Point(506, 5);
-      this.algorithmStartButton.Name = "algorithmStartButton";
-      this.algorithmStartButton.Size = new System.Drawing.Size(26, 23);
-      this.algorithmStartButton.TabIndex = 3;
-      this.algorithmStartButton.Text = "Start";
-      this.algorithmStartButton.UseVisualStyleBackColor = true;
-      this.algorithmStartButton.Click += new System.EventHandler(this.algorithmStartButton_Click);
       // 
       // ExpertSystemView
@@ -368,6 +439,9 @@
       this.okbTabPage.ResumeLayout(false);
       this.problemInstancesTabPage.ResumeLayout(false);
-      this.instancesDropPanel.ResumeLayout(false);
-      this.instancesDropPanel.PerformLayout();
+      this.problemInstancesTabPage.PerformLayout();
+      this.problemInstancesTabControl.ResumeLayout(false);
+      this.instancesTabPage.ResumeLayout(false);
+      this.mapTabPage.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.instanceMapChart)).EndInit();
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -391,12 +465,16 @@
     private System.Windows.Forms.TabPage okbTabPage;
     private System.Windows.Forms.TabPage problemInstancesTabPage;
-    private System.Windows.Forms.Panel instancesDropPanel;
     private System.Windows.Forms.Button refreshMapButton;
-    private System.Windows.Forms.Label dragFLAHereLabel;
-    private MainForm.WindowsForms.ViewHost problemInstancesView;
     private System.Windows.Forms.Button okbDownloadButton;
     private System.Windows.Forms.Panel progressPanel;
     private MainForm.WindowsForms.ViewHost kbViewHost;
     private System.Windows.Forms.Button algorithmStartButton;
+    private System.Windows.Forms.TabControl problemInstancesTabControl;
+    private System.Windows.Forms.TabPage instancesTabPage;
+    private MainForm.WindowsForms.ViewHost problemInstancesView;
+    private System.Windows.Forms.TabPage mapTabPage;
+    private Visualization.ChartControlsExtensions.EnhancedChart instanceMapChart;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ComboBox projectionComboBox;
   }
 }
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/ExpertSystemView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/ExpertSystemView.cs	(revision 13560)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/ExpertSystemView.cs	(revision 13561)
@@ -21,9 +21,9 @@
 
 using System;
-using System.Collections;
 using System.ComponentModel;
 using System.Linq;
+using System.Text.RegularExpressions;
 using System.Windows.Forms;
-using HeuristicLab.Common;
+using System.Windows.Forms.DataVisualization.Charting;
 using HeuristicLab.Common.Resources;
 using HeuristicLab.Core.Views;
@@ -172,8 +172,8 @@
 
     #region Control events
-    private void maxEvaluationsTextBox_Validating(object sender, CancelEventArgs e) {
+    private void MaxEvaluationsTextBoxOnValidating(object sender, CancelEventArgs e) {
       if (SuppressEvents) return;
       if (InvokeRequired) {
-        Invoke((Action<object, CancelEventArgs>)maxEvaluationsTextBox_Validating, sender, e);
+        Invoke((Action<object, CancelEventArgs>)MaxEvaluationsTextBoxOnValidating, sender, e);
         return;
       }
@@ -189,47 +189,23 @@
     }
     #endregion
-
-    private bool validDragOperation;
-    private void instancesDropPanel_DragEnter(object sender, DragEventArgs e) {
-      validDragOperation = false;
-      if (!ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IRun)) {
-        validDragOperation = true;
-      } else if (!ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable)) {
-        validDragOperation = true;
-        var items = (IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
-        foreach (object item in items)
-          validDragOperation = validDragOperation && (item is IRun);
-      }
-    }
-    private void instancesDropPanel_DragOver(object sender, DragEventArgs e) {
-      e.Effect = DragDropEffects.None;
-      if (!validDragOperation) return;
-      if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
-      else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
-      else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
-      else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
-      else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
-    }
-    private void instancesDropPanel_DragDrop(object sender, DragEventArgs e) {
-      if (e.Effect == DragDropEffects.None) return;
-      if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IRun) {
-        var item = (IRun)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
-        Content.ProblemInstances.Add(e.Effect.HasFlag(DragDropEffects.Copy) ? (IRun)item.Clone() : item);
-      } else if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
-        var items = ((IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat)).Cast<IRun>();
-        if (e.Effect.HasFlag(DragDropEffects.Copy)) {
-          var cloner = new Cloner();
-          items = items.Select(x => cloner.Clone(x));
-        }
-        Content.ProblemInstances.AddRange(items);
-      }
-    }
     #endregion
 
-    private void refreshMapButton_Click(object sender, EventArgs e) {
-      Content.UpdateInstanceMap();
-    }
-
-    private void okbDownloadButton_Click(object sender, EventArgs e) {
+    private void RefreshMapButtonOnClick(object sender, EventArgs e) {
+      Content.UpdateInstanceProjection();
+      UpdateProjectionComboBox();
+    }
+
+    private void UpdateProjectionComboBox() {
+      projectionComboBox.Items.Clear();
+      var projStrings = Content.ProblemInstances
+        .SelectMany(x => x.Results.Where(y => Regex.IsMatch(y.Key, "^Projection[.].*[.][XY]$")))
+        .Select(x => Regex.Match(x.Key, "Projection[.](?<g>.*)[.][XY]").Groups["g"].Value)
+        .Distinct();
+      foreach (var str in projStrings) {
+        projectionComboBox.Items.Add(str);
+      }
+    }
+
+    private void OkbDownloadButtonOnClick(object sender, EventArgs e) {
       if (Content.Problem.ProblemId < 0) {
         MessageBox.Show("Please select a problem instance first.");
@@ -254,5 +230,5 @@
     }
 
-    private void algorithmStartButton_Click(object sender, EventArgs e) {
+    private void AlgorithmStartButtonOnClick(object sender, EventArgs e) {
       var selectedInstance = (IAlgorithm)suggestedInstancesComboBox.SelectedItem;
       var clone = (IAlgorithm)selectedInstance.Clone();
@@ -261,4 +237,35 @@
       algorithmViewHost.Content = clone.Results;
     }
+
+    private void ProjectionComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
+      if (projectionComboBox.SelectedIndex < 0) return;
+      var projection = (string)projectionComboBox.SelectedItem;
+      var instancesSeries = instanceMapChart.Series["InstancesSeries"];
+      var currentInstanceSeries = instanceMapChart.Series["CurrentInstanceSeries"];
+
+      instancesSeries.Points.Clear();
+      currentInstanceSeries.Points.Clear();
+
+      foreach (var run in Content.ProblemInstances) {
+        var xKey = "Projection." + projection + ".X";
+        var yKey = "Projection." + projection + ".Y";
+        if (!run.Results.ContainsKey(xKey) || !run.Results.ContainsKey(yKey)
+          || !(run.Results[xKey] is Data.DoubleValue) || !(run.Results[yKey] is Data.DoubleValue)) continue;
+        var x = ((Data.DoubleValue)run.Results[xKey]).Value;
+        var y = ((Data.DoubleValue)run.Results[yKey]).Value;
+        var dataPoint = new DataPoint(x, y) {
+          Label = run.Name
+        };
+        instancesSeries.Points.Add(dataPoint);
+      }
+
+      var curPoint = Content.ProjectCurrentInstance(projection);
+      if (curPoint != null) {
+        var dp = new DataPoint(curPoint.Item1, curPoint.Item2) {
+          Label = Content.Problem.Problem.Name
+        };
+        currentInstanceSeries.Points.Add(dp);
+      }
+    }
   }
 }
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/HeuristicLab.OptimizationExpertSystem.Views-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/HeuristicLab.OptimizationExpertSystem.Views-3.3.csproj	(revision 13560)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Views/3.3/HeuristicLab.OptimizationExpertSystem.Views-3.3.csproj	(revision 13561)
@@ -148,4 +148,5 @@
     <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystem.cs	(revision 13560)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystem.cs	(revision 13561)
@@ -116,4 +116,7 @@
     private BidirectionalDictionary<long, IAlgorithm> algorithmId2AlgorithmInstanceMapping;
 
+    [Storable]
+    private Run currentInstance;
+
     private bool Maximization {
       get {
@@ -140,4 +143,5 @@
         algorithmId2AlgorithmInstanceMapping.Add(kvp.Key, cloner.Clone(kvp.Value));
       }
+      currentInstance = cloner.Clone(original.currentInstance);
       RegisterEventHandlers();
     }
@@ -188,15 +192,67 @@
     }
 
-    public void UpdateInstanceMap() {
-      var flaValues = ProblemInstances.ResultNames
-                      .Where(x => x.StartsWith("Characteristic.")
-                        && ProblemInstances.All(y => y.Results.ContainsKey(x) && y.Results[x] is DoubleValue))
-                      .Select(x => x).ToList();
-      var ds = new double[ProblemInstances.Count, flaValues.Count];
-      var instanceCounter = 0;
-      foreach (var instance in ProblemInstances) {
-        for (var feature = 0; feature < flaValues.Count; feature++)
-          ds[instanceCounter, feature] = ((DoubleValue)instance.Results[flaValues[feature]]).Value;
-        instanceCounter++;
+    public void UpdateInstanceProjection() {
+      currentInstance = null;
+      var filter = new HashSet<string>();
+
+      if (Problem.ProblemId != -1) {
+        currentInstance = new Run { Name = Problem.Name };
+        Problem.Problem.CollectParameterValues(currentInstance.Parameters);
+        foreach (var c in RunCreationClient.GetCharacteristicValues(Problem.ProblemId)) {
+          var key = "Characteristic." + c.Name;
+          currentInstance.Results.Add(key, RunCreationClient.Instance.ConvertToItem(c));
+          filter.Add(key);
+        }
+      }
+      // TODO: There is a problem with missing values that has to be solved
+      // The common set of characteristics among all problems may be too small to be useful
+      // It has to be decided somehow which problem instances to include in order to obtain the set of features that is expressive and available
+      var allCharacteristics = ProblemInstances.Select(x => new HashSet<string>(x.Results.Where(y => y.Key.StartsWith("Characteristic.", StringComparison.Ordinal)).Select(y => y.Key))).ToList();
+      var commonCharacteristics = filter.Count > 0 ? filter : allCharacteristics[0];
+      for (var i = 0; i < allCharacteristics.Count; i++)
+        commonCharacteristics.IntersectWith(allCharacteristics[i]);
+
+      if (commonCharacteristics.Count == 0) return;
+
+      var instances = new Dictionary<string, double[]>();
+      foreach (var i in ProblemInstances)
+        instances[i.Name] = i.Results.Where(x => commonCharacteristics.Contains(x.Key)).OrderBy(x => x.Key).Select(x => (double)((dynamic)x.Value).Value).ToArray();
+      if (currentInstance != null)
+        instances[currentInstance.Name] = currentInstance.Results.Where(x => commonCharacteristics.Contains(x.Key)).OrderBy(x => x.Key).Select(x => (double)((dynamic)x.Value).Value).ToArray();
+
+      var allValues = instances.SelectMany(x => x.Value).ToList();
+      var avg = allValues.Average();
+      var stdev = allValues.StandardDeviation();
+
+      // normalize characteristic values by transforming them to their z-score
+      foreach (var key in instances.Keys.ToList()) {
+        var arr = instances[key];
+        for (var i = 0; i < arr.Length; i++) {
+          arr[i] = (arr[i] - avg) / stdev;
+        }
+      }
+
+      var key2Idx = new BidirectionalDictionary<string, int>();
+      foreach (var kvp in instances.Select((k, i) => new { Index = i, Key = k.Key }))
+        key2Idx.Add(kvp.Key, kvp.Index);
+
+      #region MDS
+      Func<double[], double[], double> euclid = (a, b) => Math.Sqrt(a.Zip(b, (x, y) => (x - y)).Sum(x => x * x));
+      var num = instances.Count;
+      var matrix = new DoubleMatrix(num, num);
+      for (var i = 0; i < num - 1; i++) {
+        for (var j = i + 1; j < num; j++) {
+          matrix[i, j] = matrix[j, i] = euclid(instances[key2Idx.GetBySecond(i)], instances[key2Idx.GetBySecond(j)]);
+        }
+      }
+
+      var coords = MultidimensionalScaling.KruskalShepard(matrix);
+      #endregion
+      #region PCA
+      var ds = new double[instances.Count, commonCharacteristics.Count];
+      foreach (var instance in instances) {
+        var arr = instance.Value;
+        for (var feature = 0; feature < arr.Length; feature++)
+          ds[key2Idx.GetByFirst(instance.Key), feature] = arr[feature];
       }
 
@@ -204,26 +260,66 @@
       double[] s2;
       double[,] v;
-      alglib.pcabuildbasis(ds, instanceCounter, flaValues.Count, out info, out s2, out v);
+      alglib.pcabuildbasis(ds, ds.GetLength(0), ds.GetLength(1), out info, out s2, out v);
+      #endregion
 
       ProblemInstances.UpdateOfRunsInProgress = true;
       try {
-        instanceCounter = 0;
         foreach (var instance in ProblemInstances) {
           double x = 0, y = 0;
-          for (var feature = 0; feature < flaValues.Count; feature++) {
-            x += ds[instanceCounter, feature] * v[feature, 0];
-            y += ds[instanceCounter, feature] * v[feature, 1];
+          for (var feature = 0; feature < ds.GetLength(1); feature++) {
+            x += ds[key2Idx.GetByFirst(instance.Name), feature] * v[feature, 0];
+            y += ds[key2Idx.GetByFirst(instance.Name), feature] * v[feature, 1];
           }
+
           IItem item;
-          if (instance.Results.TryGetValue("Projection.PCA1", out item)) {
+          if (instance.Results.TryGetValue("Projection.PCA.X", out item)) {
             ((DoubleValue)item).Value = x;
-          } else instance.Results.Add("Projection.PCA1", new DoubleValue(x));
-          if (instance.Results.TryGetValue("Projection.PCA2", out item)) {
+          } else instance.Results.Add("Projection.PCA.X", new DoubleValue(x));
+          if (instance.Results.TryGetValue("Projection.PCA.Y", out item)) {
             ((DoubleValue)item).Value = y;
-          } else instance.Results.Add("Projection.PCA2", new DoubleValue(y));
-
-          instanceCounter++;
+          } else instance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
+
+          if (instance.Results.TryGetValue("Projection.MDS.X", out item)) {
+            ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(instance.Name), 0];
+          } else instance.Results.Add("Projection.MDS.X", new DoubleValue(coords[key2Idx.GetByFirst(instance.Name), 0]));
+          if (instance.Results.TryGetValue("Projection.MDS.Y", out item)) {
+            ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(instance.Name), 1];
+          } else instance.Results.Add("Projection.MDS.Y", new DoubleValue(coords[key2Idx.GetByFirst(instance.Name), 1]));
         }
       } finally { ProblemInstances.UpdateOfRunsInProgress = false; }
+
+      if (currentInstance != null) {
+        double x = 0, y = 0;
+        for (var feature = 0; feature < ds.GetLength(1); feature++) {
+          x += ds[key2Idx.GetByFirst(currentInstance.Name), feature] * v[feature, 0];
+          y += ds[key2Idx.GetByFirst(currentInstance.Name), feature] * v[feature, 1];
+        }
+
+        IItem item;
+        if (currentInstance.Results.TryGetValue("Projection.PCA.X", out item)) {
+          ((DoubleValue)item).Value = x;
+        } else currentInstance.Results.Add("Projection.PCA.X", new DoubleValue(x));
+        if (currentInstance.Results.TryGetValue("Projection.PCA.Y", out item)) {
+          ((DoubleValue)item).Value = y;
+        } else currentInstance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
+
+        if (currentInstance.Results.TryGetValue("Projection.MDS.X", out item)) {
+          ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(currentInstance.Name), 0];
+        } else currentInstance.Results.Add("Projection.MDS.X", new DoubleValue(coords[key2Idx.GetByFirst(currentInstance.Name), 0]));
+        if (currentInstance.Results.TryGetValue("Projection.MDS.Y", out item)) {
+          ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(currentInstance.Name), 1];
+        } else currentInstance.Results.Add("Projection.MDS.Y", new DoubleValue(coords[key2Idx.GetByFirst(currentInstance.Name), 1]));
+      }
+    }
+
+    public Tuple<double, double> ProjectCurrentInstance(string projection) {
+      if (currentInstance == null) return null;
+      var xKey = "Projection." + projection + ".X";
+      var yKey = "Projection." + projection + ".Y";
+      if (!currentInstance.Results.ContainsKey(xKey) || !currentInstance.Results.ContainsKey(yKey))
+        return null;
+      var x = ((DoubleValue)currentInstance.Results[xKey]).Value;
+      var y = ((DoubleValue)currentInstance.Results[yKey]).Value;
+      return Tuple.Create(x, y);
     }
 
