Index: branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs	(revision 12834)
+++ branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs	(revision 12838)
@@ -47,19 +47,33 @@
       this.dataTableComboBox = new System.Windows.Forms.ComboBox();
       this.dataTableLabel = new System.Windows.Forms.Label();
-      this.viewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
       this.groupLabel = new System.Windows.Forms.Label();
       this.groupComboBox = new System.Windows.Forms.ComboBox();
-      this.logScalingCheckBox = new System.Windows.Forms.CheckBox();
+      this.targetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
       this.targetsTextBox = new System.Windows.Forms.TextBox();
       this.targetsLabel = new System.Windows.Forms.Label();
       this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
-      this.fixedTargetButton = new System.Windows.Forms.Button();
+      this.addTargetsAsResultButton = new System.Windows.Forms.Button();
       this.generateTargetsButton = new System.Windows.Forms.Button();
       this.toolTip = new System.Windows.Forms.ToolTip(this.components);
       this.budgetsLabel = new System.Windows.Forms.Label();
       this.budgetsTextBox = new System.Windows.Forms.TextBox();
-      this.fixedCostButton = new System.Windows.Forms.Button();
-      this.allOrEachTargetCheckBox = new System.Windows.Forms.CheckBox();
+      this.addBudgetsAsResultButton = new System.Windows.Forms.Button();
+      this.eachOrAllTargetCheckBox = new System.Windows.Forms.CheckBox();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.byTargetTabPage = new System.Windows.Forms.TabPage();
+      this.byTargetViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.byCostTabPage = new System.Windows.Forms.TabPage();
+      this.eachOrAllBudgetsCheckBox = new System.Windows.Forms.CheckBox();
+      this.generateBudgetsButton = new System.Windows.Forms.Button();
+      this.byCostViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.byTableTabPage = new System.Windows.Forms.TabPage();
+      this.dataGridView1 = new System.Windows.Forms.DataGridView();
+      this.budgetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.byTargetTabPage.SuspendLayout();
+      this.byCostTabPage.SuspendLayout();
+      this.byTableTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
       this.SuspendLayout();
       // 
@@ -72,5 +86,5 @@
       this.dataTableComboBox.Location = new System.Drawing.Point(69, 30);
       this.dataTableComboBox.Name = "dataTableComboBox";
-      this.dataTableComboBox.Size = new System.Drawing.Size(455, 21);
+      this.dataTableComboBox.Size = new System.Drawing.Size(582, 21);
       this.dataTableComboBox.TabIndex = 0;
       this.dataTableComboBox.SelectedIndexChanged += new System.EventHandler(this.dataTableComboBox_SelectedIndexChanged);
@@ -85,20 +99,4 @@
       this.dataTableLabel.Text = "DataTable:";
       // 
-      // viewHost
-      // 
-      this.viewHost.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.viewHost.Caption = "View";
-      this.viewHost.Content = null;
-      this.viewHost.Enabled = false;
-      this.viewHost.Location = new System.Drawing.Point(4, 90);
-      this.viewHost.Name = "viewHost";
-      this.viewHost.ReadOnly = false;
-      this.viewHost.Size = new System.Drawing.Size(520, 258);
-      this.viewHost.TabIndex = 2;
-      this.viewHost.ViewsLabelVisible = true;
-      this.viewHost.ViewType = null;
-      // 
       // groupLabel
       // 
@@ -118,19 +116,19 @@
       this.groupComboBox.Location = new System.Drawing.Point(69, 3);
       this.groupComboBox.Name = "groupComboBox";
-      this.groupComboBox.Size = new System.Drawing.Size(455, 21);
+      this.groupComboBox.Size = new System.Drawing.Size(582, 21);
       this.groupComboBox.TabIndex = 4;
       this.groupComboBox.SelectedIndexChanged += new System.EventHandler(this.groupComboBox_SelectedIndexChanged);
       // 
-      // logScalingCheckBox
-      // 
-      this.logScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.logScalingCheckBox.AutoSize = true;
-      this.logScalingCheckBox.Location = new System.Drawing.Point(0, 354);
-      this.logScalingCheckBox.Name = "logScalingCheckBox";
-      this.logScalingCheckBox.Size = new System.Drawing.Size(112, 17);
-      this.logScalingCheckBox.TabIndex = 5;
-      this.logScalingCheckBox.Text = "logarithmic scaling";
-      this.logScalingCheckBox.UseVisualStyleBackColor = true;
-      this.logScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
+      // targetLogScalingCheckBox
+      // 
+      this.targetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.targetLogScalingCheckBox.AutoSize = true;
+      this.targetLogScalingCheckBox.Location = new System.Drawing.Point(9, 391);
+      this.targetLogScalingCheckBox.Name = "targetLogScalingCheckBox";
+      this.targetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
+      this.targetLogScalingCheckBox.TabIndex = 5;
+      this.targetLogScalingCheckBox.Text = "logarithmic scaling";
+      this.targetLogScalingCheckBox.UseVisualStyleBackColor = true;
+      this.targetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
       // 
       // targetsTextBox
@@ -138,7 +136,7 @@
       this.targetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-      this.targetsTextBox.Location = new System.Drawing.Point(69, 57);
+      this.targetsTextBox.Location = new System.Drawing.Point(65, 8);
       this.targetsTextBox.Name = "targetsTextBox";
-      this.targetsTextBox.Size = new System.Drawing.Size(209, 20);
+      this.targetsTextBox.Size = new System.Drawing.Size(320, 20);
       this.targetsTextBox.TabIndex = 6;
       this.toolTip.SetToolTip(this.targetsTextBox, "The order of the targets is important, first to-hit targets\r\nshould be given firs" +
@@ -150,5 +148,5 @@
       // 
       this.targetsLabel.AutoSize = true;
-      this.targetsLabel.Location = new System.Drawing.Point(3, 60);
+      this.targetsLabel.Location = new System.Drawing.Point(6, 11);
       this.targetsLabel.Name = "targetsLabel";
       this.targetsLabel.Size = new System.Drawing.Size(46, 13);
@@ -160,19 +158,19 @@
       this.errorProvider.ContainerControl = this;
       // 
-      // fixedTargetButton
-      // 
-      this.fixedTargetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.fixedTargetButton.Location = new System.Drawing.Point(435, 54);
-      this.fixedTargetButton.Name = "fixedTargetButton";
-      this.fixedTargetButton.Size = new System.Drawing.Size(89, 23);
-      this.fixedTargetButton.TabIndex = 7;
-      this.fixedTargetButton.Text = "Add as Result";
-      this.fixedTargetButton.UseVisualStyleBackColor = true;
-      this.fixedTargetButton.Click += new System.EventHandler(this.fixedTargetButton_Click);
+      // addTargetsAsResultButton
+      // 
+      this.addTargetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.addTargetsAsResultButton.Location = new System.Drawing.Point(551, 6);
+      this.addTargetsAsResultButton.Name = "addTargetsAsResultButton";
+      this.addTargetsAsResultButton.Size = new System.Drawing.Size(89, 23);
+      this.addTargetsAsResultButton.TabIndex = 7;
+      this.addTargetsAsResultButton.Text = "Add as Result";
+      this.addTargetsAsResultButton.UseVisualStyleBackColor = true;
+      this.addTargetsAsResultButton.Click += new System.EventHandler(this.addTargetsAsResultButton_Click);
       // 
       // generateTargetsButton
       // 
       this.generateTargetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.generateTargetsButton.Location = new System.Drawing.Point(340, 54);
+      this.generateTargetsButton.Location = new System.Drawing.Point(456, 6);
       this.generateTargetsButton.Name = "generateTargetsButton";
       this.generateTargetsButton.Size = new System.Drawing.Size(89, 23);
@@ -184,7 +182,6 @@
       // budgetsLabel
       // 
-      this.budgetsLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
       this.budgetsLabel.AutoSize = true;
-      this.budgetsLabel.Location = new System.Drawing.Point(235, 353);
+      this.budgetsLabel.Location = new System.Drawing.Point(6, 11);
       this.budgetsLabel.Name = "budgetsLabel";
       this.budgetsLabel.Size = new System.Drawing.Size(49, 13);
@@ -194,56 +191,187 @@
       // budgetsTextBox
       // 
-      this.budgetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.budgetsTextBox.Location = new System.Drawing.Point(290, 350);
+      this.budgetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.budgetsTextBox.Location = new System.Drawing.Point(65, 8);
       this.budgetsTextBox.Name = "budgetsTextBox";
-      this.budgetsTextBox.Size = new System.Drawing.Size(139, 20);
+      this.budgetsTextBox.Size = new System.Drawing.Size(320, 20);
       this.budgetsTextBox.TabIndex = 6;
-      this.budgetsTextBox.Text = "1e2 ; 1e3 ; 1e4 ; 1e5 ; 1e6";
-      this.budgetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.targetsTextBox_Validating);
-      // 
-      // fixedCostButton
-      // 
-      this.fixedCostButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-      this.fixedCostButton.Location = new System.Drawing.Point(435, 348);
-      this.fixedCostButton.Name = "fixedCostButton";
-      this.fixedCostButton.Size = new System.Drawing.Size(89, 23);
-      this.fixedCostButton.TabIndex = 7;
-      this.fixedCostButton.Text = "Add as Result";
-      this.fixedCostButton.UseVisualStyleBackColor = true;
-      this.fixedCostButton.Click += new System.EventHandler(this.fixedCostButton_Click);
-      // 
-      // allOrEachTargetCheckBox
-      // 
-      this.allOrEachTargetCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.allOrEachTargetCheckBox.AutoSize = true;
-      this.allOrEachTargetCheckBox.Location = new System.Drawing.Point(298, 59);
-      this.allOrEachTargetCheckBox.Name = "allOrEachTargetCheckBox";
-      this.allOrEachTargetCheckBox.Size = new System.Drawing.Size(36, 17);
-      this.allOrEachTargetCheckBox.TabIndex = 8;
-      this.allOrEachTargetCheckBox.Text = "all";
-      this.allOrEachTargetCheckBox.UseVisualStyleBackColor = true;
-      this.allOrEachTargetCheckBox.CheckedChanged += new System.EventHandler(this.allOrEachTargetCheckBox_CheckedChanged);
+      this.budgetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.budgetsTextBox_Validating);
+      // 
+      // addBudgetsAsResultButton
+      // 
+      this.addBudgetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.addBudgetsAsResultButton.Location = new System.Drawing.Point(551, 6);
+      this.addBudgetsAsResultButton.Name = "addBudgetsAsResultButton";
+      this.addBudgetsAsResultButton.Size = new System.Drawing.Size(89, 23);
+      this.addBudgetsAsResultButton.TabIndex = 7;
+      this.addBudgetsAsResultButton.Text = "Add as Result";
+      this.addBudgetsAsResultButton.UseVisualStyleBackColor = true;
+      this.addBudgetsAsResultButton.Click += new System.EventHandler(this.addBudgetsAsResultButton_Click);
+      // 
+      // eachOrAllTargetCheckBox
+      // 
+      this.eachOrAllTargetCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.eachOrAllTargetCheckBox.AutoSize = true;
+      this.eachOrAllTargetCheckBox.Location = new System.Drawing.Point(414, 10);
+      this.eachOrAllTargetCheckBox.Name = "eachOrAllTargetCheckBox";
+      this.eachOrAllTargetCheckBox.Size = new System.Drawing.Size(36, 17);
+      this.eachOrAllTargetCheckBox.TabIndex = 8;
+      this.eachOrAllTargetCheckBox.Text = "all";
+      this.eachOrAllTargetCheckBox.UseVisualStyleBackColor = true;
+      this.eachOrAllTargetCheckBox.CheckedChanged += new System.EventHandler(this.eachOrAllTargetCheckBox_CheckedChanged);
+      // 
+      // tabControl
+      // 
+      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.byTargetTabPage);
+      this.tabControl.Controls.Add(this.byCostTabPage);
+      this.tabControl.Controls.Add(this.byTableTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 57);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(654, 440);
+      this.tabControl.TabIndex = 9;
+      // 
+      // byTargetTabPage
+      // 
+      this.byTargetTabPage.Controls.Add(this.byTargetViewHost);
+      this.byTargetTabPage.Controls.Add(this.targetLogScalingCheckBox);
+      this.byTargetTabPage.Controls.Add(this.targetsLabel);
+      this.byTargetTabPage.Controls.Add(this.eachOrAllTargetCheckBox);
+      this.byTargetTabPage.Controls.Add(this.targetsTextBox);
+      this.byTargetTabPage.Controls.Add(this.generateTargetsButton);
+      this.byTargetTabPage.Controls.Add(this.addTargetsAsResultButton);
+      this.byTargetTabPage.Location = new System.Drawing.Point(4, 22);
+      this.byTargetTabPage.Name = "byTargetTabPage";
+      this.byTargetTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.byTargetTabPage.Size = new System.Drawing.Size(646, 414);
+      this.byTargetTabPage.TabIndex = 0;
+      this.byTargetTabPage.Text = "Performance by Target";
+      this.byTargetTabPage.UseVisualStyleBackColor = true;
+      // 
+      // byTargetViewHost
+      // 
+      this.byTargetViewHost.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.byTargetViewHost.Caption = "View";
+      this.byTargetViewHost.Content = null;
+      this.byTargetViewHost.Enabled = false;
+      this.byTargetViewHost.Location = new System.Drawing.Point(3, 34);
+      this.byTargetViewHost.Name = "byTargetViewHost";
+      this.byTargetViewHost.ReadOnly = false;
+      this.byTargetViewHost.Size = new System.Drawing.Size(640, 351);
+      this.byTargetViewHost.TabIndex = 9;
+      this.byTargetViewHost.ViewsLabelVisible = true;
+      this.byTargetViewHost.ViewType = null;
+      // 
+      // byCostTabPage
+      // 
+      this.byCostTabPage.Controls.Add(this.budgetLogScalingCheckBox);
+      this.byCostTabPage.Controls.Add(this.eachOrAllBudgetsCheckBox);
+      this.byCostTabPage.Controls.Add(this.generateBudgetsButton);
+      this.byCostTabPage.Controls.Add(this.byCostViewHost);
+      this.byCostTabPage.Controls.Add(this.budgetsLabel);
+      this.byCostTabPage.Controls.Add(this.addBudgetsAsResultButton);
+      this.byCostTabPage.Controls.Add(this.budgetsTextBox);
+      this.byCostTabPage.Location = new System.Drawing.Point(4, 22);
+      this.byCostTabPage.Name = "byCostTabPage";
+      this.byCostTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.byCostTabPage.Size = new System.Drawing.Size(646, 414);
+      this.byCostTabPage.TabIndex = 1;
+      this.byCostTabPage.Text = "Performance by Cost";
+      this.byCostTabPage.UseVisualStyleBackColor = true;
+      // 
+      // eachOrAllBudgetsCheckBox
+      // 
+      this.eachOrAllBudgetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.eachOrAllBudgetsCheckBox.AutoSize = true;
+      this.eachOrAllBudgetsCheckBox.Location = new System.Drawing.Point(414, 10);
+      this.eachOrAllBudgetsCheckBox.Name = "eachOrAllBudgetsCheckBox";
+      this.eachOrAllBudgetsCheckBox.Size = new System.Drawing.Size(36, 17);
+      this.eachOrAllBudgetsCheckBox.TabIndex = 10;
+      this.eachOrAllBudgetsCheckBox.Text = "all";
+      this.eachOrAllBudgetsCheckBox.UseVisualStyleBackColor = true;
+      this.eachOrAllBudgetsCheckBox.CheckedChanged += new System.EventHandler(this.eachOrAllBudgetsCheckBox_CheckedChanged);
+      // 
+      // generateBudgetsButton
+      // 
+      this.generateBudgetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.generateBudgetsButton.Location = new System.Drawing.Point(456, 6);
+      this.generateBudgetsButton.Name = "generateBudgetsButton";
+      this.generateBudgetsButton.Size = new System.Drawing.Size(89, 23);
+      this.generateBudgetsButton.TabIndex = 9;
+      this.generateBudgetsButton.Text = "Generate...";
+      this.generateBudgetsButton.UseVisualStyleBackColor = true;
+      this.generateBudgetsButton.Click += new System.EventHandler(this.generateBudgetsButton_Click);
+      // 
+      // byCostViewHost
+      // 
+      this.byCostViewHost.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.byCostViewHost.Caption = "View";
+      this.byCostViewHost.Content = null;
+      this.byCostViewHost.Enabled = false;
+      this.byCostViewHost.Location = new System.Drawing.Point(3, 34);
+      this.byCostViewHost.Name = "byCostViewHost";
+      this.byCostViewHost.ReadOnly = false;
+      this.byCostViewHost.Size = new System.Drawing.Size(640, 351);
+      this.byCostViewHost.TabIndex = 8;
+      this.byCostViewHost.ViewsLabelVisible = true;
+      this.byCostViewHost.ViewType = null;
+      // 
+      // byTableTabPage
+      // 
+      this.byTableTabPage.Controls.Add(this.dataGridView1);
+      this.byTableTabPage.Location = new System.Drawing.Point(4, 22);
+      this.byTableTabPage.Name = "byTableTabPage";
+      this.byTableTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.byTableTabPage.Size = new System.Drawing.Size(646, 388);
+      this.byTableTabPage.TabIndex = 2;
+      this.byTableTabPage.Text = "Expected Runtime Tables";
+      this.byTableTabPage.UseVisualStyleBackColor = true;
+      // 
+      // dataGridView1
+      // 
+      this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.dataGridView1.Location = new System.Drawing.Point(3, 3);
+      this.dataGridView1.Name = "dataGridView1";
+      this.dataGridView1.Size = new System.Drawing.Size(640, 382);
+      this.dataGridView1.TabIndex = 0;
+      // 
+      // budgetLogScalingCheckBox
+      // 
+      this.budgetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.budgetLogScalingCheckBox.AutoSize = true;
+      this.budgetLogScalingCheckBox.Location = new System.Drawing.Point(9, 391);
+      this.budgetLogScalingCheckBox.Name = "budgetLogScalingCheckBox";
+      this.budgetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
+      this.budgetLogScalingCheckBox.TabIndex = 11;
+      this.budgetLogScalingCheckBox.Text = "logarithmic scaling";
+      this.budgetLogScalingCheckBox.UseVisualStyleBackColor = true;
       // 
       // RunCollectionRLDView
       // 
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
-      this.Controls.Add(this.allOrEachTargetCheckBox);
-      this.Controls.Add(this.generateTargetsButton);
-      this.Controls.Add(this.fixedCostButton);
-      this.Controls.Add(this.fixedTargetButton);
-      this.Controls.Add(this.budgetsTextBox);
-      this.Controls.Add(this.targetsTextBox);
-      this.Controls.Add(this.logScalingCheckBox);
+      this.Controls.Add(this.tabControl);
       this.Controls.Add(this.groupComboBox);
       this.Controls.Add(this.groupLabel);
-      this.Controls.Add(this.budgetsLabel);
-      this.Controls.Add(this.viewHost);
-      this.Controls.Add(this.targetsLabel);
       this.Controls.Add(this.dataTableLabel);
       this.Controls.Add(this.dataTableComboBox);
       this.Name = "RunCollectionRLDView";
-      this.Size = new System.Drawing.Size(527, 374);
+      this.Size = new System.Drawing.Size(654, 497);
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.byTargetTabPage.ResumeLayout(false);
+      this.byTargetTabPage.PerformLayout();
+      this.byCostTabPage.ResumeLayout(false);
+      this.byCostTabPage.PerformLayout();
+      this.byTableTabPage.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -255,18 +383,27 @@
     private System.Windows.Forms.ComboBox dataTableComboBox;
     private System.Windows.Forms.Label dataTableLabel;
-    private MainForm.WindowsForms.ViewHost viewHost;
     private System.Windows.Forms.Label groupLabel;
     private System.Windows.Forms.ComboBox groupComboBox;
-    private System.Windows.Forms.CheckBox logScalingCheckBox;
+    private System.Windows.Forms.CheckBox targetLogScalingCheckBox;
     private System.Windows.Forms.TextBox targetsTextBox;
     private System.Windows.Forms.Label targetsLabel;
     protected System.Windows.Forms.ErrorProvider errorProvider;
-    private System.Windows.Forms.Button fixedTargetButton;
+    private System.Windows.Forms.Button addTargetsAsResultButton;
     private System.Windows.Forms.Button generateTargetsButton;
     private System.Windows.Forms.ToolTip toolTip;
-    private System.Windows.Forms.Button fixedCostButton;
+    private System.Windows.Forms.Button addBudgetsAsResultButton;
     private System.Windows.Forms.TextBox budgetsTextBox;
     private System.Windows.Forms.Label budgetsLabel;
-    private System.Windows.Forms.CheckBox allOrEachTargetCheckBox;
+    private System.Windows.Forms.CheckBox eachOrAllTargetCheckBox;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage byTargetTabPage;
+    private MainForm.WindowsForms.ViewHost byTargetViewHost;
+    private System.Windows.Forms.TabPage byCostTabPage;
+    private System.Windows.Forms.TabPage byTableTabPage;
+    private System.Windows.Forms.DataGridView dataGridView1;
+    private MainForm.WindowsForms.ViewHost byCostViewHost;
+    private System.Windows.Forms.CheckBox eachOrAllBudgetsCheckBox;
+    private System.Windows.Forms.Button generateBudgetsButton;
+    private System.Windows.Forms.CheckBox budgetLogScalingCheckBox;
   }
 }
Index: branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 12834)
+++ branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 12838)
@@ -40,16 +40,24 @@
 
     private static readonly Color[] colors = new[] {
-      Color.FromArgb(0x20, 0x4A, 0x87),
-      Color.FromArgb(0xC1, 0x7D, 0x11),
-      Color.FromArgb(0x4E, 0x9A, 0x06),
+      Color.FromArgb(0x40, 0x6A, 0xB7),
+      Color.FromArgb(0xB1, 0x6D, 0x01),
+      Color.FromArgb(0x4E, 0x8A, 0x06),
       Color.FromArgb(0x75, 0x50, 0x7B),
       Color.FromArgb(0x72, 0x9F, 0xCF),
       Color.FromArgb(0xA4, 0x00, 0x00),
       Color.FromArgb(0xAD, 0x7F, 0xA8),
-      Color.FromArgb(0xF5, 0x79, 0x00),
+      Color.FromArgb(0x29, 0x50, 0xCF),
+      Color.FromArgb(0x90, 0xB0, 0x60),
+      Color.FromArgb(0xF5, 0x89, 0x30),
       Color.FromArgb(0x55, 0x57, 0x53),
-      Color.FromArgb(0xEF, 0x29, 0x29),
-      Color.FromArgb(0xED, 0xD4, 0x00),
-      Color.FromArgb(0x73, 0xD2, 0x16),
+      Color.FromArgb(0xEF, 0x59, 0x59),
+      Color.FromArgb(0xED, 0xD4, 0x30),
+      Color.FromArgb(0x63, 0xC2, 0x16),
+    };
+    private static readonly DataRowVisualProperties.DataRowLineStyle[] lineStyles = new[] {
+      DataRowVisualProperties.DataRowLineStyle.Solid,
+      DataRowVisualProperties.DataRowLineStyle.Dash,
+      DataRowVisualProperties.DataRowLineStyle.DashDot,
+      DataRowVisualProperties.DataRowLineStyle.Dot
     };
 
@@ -59,15 +67,20 @@
     }
 
-    private double[] levels;
+    private double[] targets;
+    private double[] budgets;
 
     private bool suppressUpdates;
-    private readonly IndexedDataTable<double> combinedDataTable;
-    public IndexedDataTable<double> CombinedDataTable {
-      get { return combinedDataTable; }
+    private readonly IndexedDataTable<double> byTargetDataTable;
+    public IndexedDataTable<double> ByTargetDataTable {
+      get { return byTargetDataTable; }
+    }
+    private readonly IndexedDataTable<double> byCostDataTable;
+    public IndexedDataTable<double> ByCostDataTable {
+      get { return byCostDataTable; }
     }
 
     public RunCollectionRLDView() {
       InitializeComponent();
-      combinedDataTable = new IndexedDataTable<double>("Combined DataTable", "A data table containing the ECDF of each of a number of groups.") {
+      byTargetDataTable = new IndexedDataTable<double>("ECDF by Target", "A data table containing the ECDF of each of a number of groups.") {
         VisualProperties = {
           YAxisTitle = "Proportion of reached targets",
@@ -76,5 +89,13 @@
         }
       };
-      viewHost.Content = combinedDataTable;
+      byTargetViewHost.Content = byTargetDataTable;
+      byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of each of a number of groups.") {
+        VisualProperties = {
+          YAxisTitle = "Proportion of required budgets",
+          YAxisMinimumFixedValue = 0, YAxisMinimumAuto = false,
+          YAxisMaximumFixedValue = 1, YAxisMaximumAuto = false
+        }
+      };
+      byCostViewHost.Content = byCostDataTable;
       suppressUpdates = false;
     }
@@ -170,5 +191,5 @@
       dataTableComboBox.Items.Clear();
       groupComboBox.Items.Clear();
-      combinedDataTable.Rows.Clear();
+      byTargetDataTable.Rows.Clear();
 
       UpdateCaption();
@@ -179,126 +200,4 @@
     }
 
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      groupComboBox.Enabled = Content != null;
-      dataTableComboBox.Enabled = Content != null;
-      fixedTargetButton.Enabled = Content != null && levels != null && dataTableComboBox.SelectedIndex >= 0;
-    }
-
-    private void UpdateRuns() {
-      if (InvokeRequired) {
-        Invoke((Action)UpdateRuns);
-        return;
-      }
-      SuspendRepaint();
-      try {
-        combinedDataTable.VisualProperties.XAxisLogScale = false;
-        combinedDataTable.Rows.Clear();
-        var table = (string)dataTableComboBox.SelectedItem;
-        if (string.IsNullOrEmpty(table)) return;
-        if (levels == null) {
-          var worstMin = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.First().Item2).Min();
-          var worstMax = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.First().Item2).Max();
-          var bestMin = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Last().Item2).Min();
-          var bestMax = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Last().Item2).Max();
-          double worst, best;
-          if (Math.Abs(bestMax - worstMin) > Math.Abs(bestMin - worstMax)) {
-            worst = worstMin;
-            best = bestMax;
-          } else {
-            worst = worstMax;
-            best = bestMin;
-          }
-          levels = Enumerable.Range(0, 11).Select(x => worst + (x / 10.0) * (best - worst)).ToArray();
-          suppressTargetsEvents = true;
-          targetsTextBox.Text = string.Join(" ; ", levels);
-          suppressTargetsEvents = false;
-        }
-        var selectedGroup = (string)groupComboBox.SelectedItem;
-        if (string.IsNullOrEmpty(selectedGroup)) return;
-        List<Tuple<string, List<IRun>>> groupedRuns;
-        if (selectedGroup == AllRuns)
-          groupedRuns = new List<Tuple<string, List<IRun>>> { Tuple.Create(AllRuns, Content.ToList()) };
-        else groupedRuns = (from r in Content
-                            group r by r.Parameters[selectedGroup].ToString() into g
-                            select Tuple.Create(g.Key, g.ToList())).ToList();
-        var xAxisTitles = new HashSet<string>();
-        var colorCount = 0;
-        var lineStyles = new[] {
-          DataRowVisualProperties.DataRowLineStyle.Solid,
-          DataRowVisualProperties.DataRowLineStyle.Dash,
-          DataRowVisualProperties.DataRowLineStyle.DashDot,
-          DataRowVisualProperties.DataRowLineStyle.Dot
-        };
-        var lineStyleCount = 0;
-        foreach (var group in groupedRuns) {
-          var hits = new Dictionary<string, SortedList<double, double>>();
-          foreach (var run in group.Item2) {
-            if (!run.Results.ContainsKey(table)) continue;
-            var resultsTable = (IndexedDataTable<double>)run.Results[table];
-            xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
-            var values = resultsTable.Rows.First().Values;
-            var maximization = values.First().Item2 < values.Last().Item2;
-            if (allOrEachTargetCheckBox.Checked) {
-              // each
-              foreach (double l in levels) {
-                var key = "-" + l.ToString();
-                if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
-                foreach (var v in values) {
-                  if (maximization && v.Item2 >= l || !maximization && v.Item2 <= l) {
-                    if (hits[key].ContainsKey(v.Item1))
-                      hits[key][v.Item1] += 1.0 / group.Item2.Count;
-                    else hits[key][v.Item1] = 1.0 / group.Item2.Count;
-                    break;
-                  }
-                }
-              }
-            } else {
-              if (!hits.ContainsKey("all")) hits.Add("all", new SortedList<double, double>());
-              // all
-              var i = 0;
-              var j = 0;
-              var current = values[j];
-              var prev = Tuple.Create(-1.0, double.NaN);
-              while (i < levels.Length) {
-                if ((double.IsNaN(prev.Item2) || prev.Item2 != current.Item2)
-                    && (maximization && current.Item2 >= levels[i]
-                        || !maximization && current.Item2 <= levels[i])) {
-                  if (hits["all"].ContainsKey(current.Item1))
-                    hits["all"][current.Item1] += 1.0 / (group.Item2.Count * levels.Length);
-                  else hits["all"][current.Item1] = 1.0 / (group.Item2.Count * levels.Length);
-                  i++;
-                } else {
-                  j++;
-                  if (j >= values.Count) break;
-                  prev = current;
-                  current = values[j];
-                }
-              }
-            }
-          }
-          foreach (var list in hits) {
-            var row = new IndexedDataRow<double>(group.Item1 + (list.Key != "all" ? list.Key : string.Empty)) {
-              VisualProperties = {
-                ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
-                LineWidth = 2,
-                Color = colors[colorCount],
-                LineStyle = lineStyles[lineStyleCount]
-              }
-            };
-            var total = 0.0;
-            foreach (var h in list.Value) {
-              total += h.Value;
-              row.Values.Add(Tuple.Create(h.Key, total));
-            }
-            combinedDataTable.Rows.Add(row);
-          }
-          colorCount = (colorCount + 1) % colors.Length;
-          if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
-        }
-        combinedDataTable.VisualProperties.XAxisTitle = string.Join(" / ", xAxisTitles);
-        combinedDataTable.VisualProperties.XAxisLogScale = combinedDataTable.Rows.Count > 0 && logScalingCheckBox.Checked;
-      } finally { ResumeRepaint(true); }
-    }
 
     private void UpdateGroupComboBox() {
@@ -333,4 +232,292 @@
     }
 
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      groupComboBox.Enabled = Content != null;
+      dataTableComboBox.Enabled = Content != null;
+      addTargetsAsResultButton.Enabled = Content != null && targets != null && dataTableComboBox.SelectedIndex >= 0;
+      addBudgetsAsResultButton.Enabled = Content != null && budgets != null && dataTableComboBox.SelectedIndex >= 0;
+    }
+
+    private void UpdateRuns() {
+      if (InvokeRequired) {
+        Invoke((Action)UpdateRuns);
+        return;
+      }
+      SuspendRepaint();
+      try {
+        UpdateResultsByTarget();
+        UpdateResultsByCost();
+      } finally { ResumeRepaint(true); }
+    }
+
+    #region Performance analysis by (multiple) target(s)
+    private void UpdateResultsByTarget() {
+      // necessary to reset log scale -> empty chart cannot use log scaling
+      byTargetDataTable.VisualProperties.XAxisLogScale = false;
+      byTargetDataTable.Rows.Clear();
+
+      var table = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(table)) return;
+
+      var selectedGroup = (string)groupComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(selectedGroup)) return;
+
+      if (targets == null) GenerateDefaultTargets(table);
+
+      List<Tuple<string, List<IRun>>> groupedRuns;
+      if (selectedGroup == AllRuns)
+        groupedRuns = new List<Tuple<string, List<IRun>>> {
+          Tuple.Create(AllRuns, Content.Where(r => r.Results.ContainsKey(table) && r.Visible).ToList())
+        };
+      else groupedRuns = (from r in Content
+                          where r.Results.ContainsKey(table) && r.Visible
+                          group r by r.Parameters[selectedGroup].ToString() into g
+                          select Tuple.Create(g.Key, g.ToList())).ToList();
+
+      var xAxisTitles = new HashSet<string>();
+      var colorCount = 0;
+      var lineStyleCount = 0;
+      var maximization = IsMaximization();
+
+      foreach (var group in groupedRuns) {
+        var hits = new Dictionary<string, SortedList<double, double>>();
+        var maxLength = 0.0;
+
+        foreach (var run in group.Item2) {
+          var resultsTable = (IndexedDataTable<double>)run.Results[table];
+          xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
+
+          if (eachOrAllTargetCheckBox.Checked) {
+            CalculateHitsForEachTarget(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
+          } else {
+            maxLength = CalculateHitsForAllTargets(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
+          }
+        }
+
+        foreach (var list in hits) {
+          var row = new IndexedDataRow<double>(list.Key) {
+            VisualProperties = {
+              ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
+              LineWidth = 2,
+              Color = colors[colorCount],
+              LineStyle = lineStyles[lineStyleCount]
+            }
+          };
+
+          var total = 0.0;
+          foreach (var h in list.Value) {
+            total += h.Value;
+            row.Values.Add(Tuple.Create(h.Key, total));
+          }
+
+          if (maxLength > 0 && (row.Values.Count == 0 || row.Values.Last().Item1 < maxLength))
+            row.Values.Add(Tuple.Create(maxLength, total));
+
+          byTargetDataTable.Rows.Add(row);
+        }
+        colorCount = (colorCount + 1) % colors.Length;
+        if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
+      }
+
+      byTargetDataTable.VisualProperties.XAxisTitle = string.Join(" / ", xAxisTitles);
+      byTargetDataTable.VisualProperties.XAxisLogScale = byTargetDataTable.Rows.Count > 0 && targetLogScalingCheckBox.Checked;
+    }
+
+    private void GenerateDefaultTargets(string table) {
+      var worst = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item2).Min()).Min();
+      var best = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item2).Max()).Max();
+      var maximization = IsMaximization();
+      if (!maximization) {
+        var h = worst;
+        worst = best;
+        best = h;
+      }
+
+      if (best == 0 || Math.Abs(best - worst) < Math.Abs(best * 2))
+        targets = Enumerable.Range(0, 11).Select(x => worst + (x / 10.0) * (best - worst)).ToArray();
+      else if (best > 0) targets = Enumerable.Range(0, 11).Select(x => best * (1.0 + (10 - x) / 10.0)).ToArray();
+      else if (best < 0) targets = Enumerable.Range(0, 11).Select(x => best / (1.0 + (10 - x) / 10.0)).ToArray();
+
+      suppressTargetsEvents = true;
+      targetsTextBox.Text = string.Join(" ; ", targets);
+      suppressTargetsEvents = false;
+    }
+
+    private void CalculateHitsForEachTarget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
+      foreach (var l in targets) {
+        var key = groupName + "-" + l;
+        if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
+        foreach (var v in row.Values) {
+          if (maximization && v.Item2 >= l || !maximization && v.Item2 <= l) {
+            if (hits[key].ContainsKey(v.Item1))
+              hits[key][v.Item1] += 1.0 / groupCount;
+            else hits[key][v.Item1] = 1.0 / groupCount;
+            break;
+          }
+        }
+      }
+    }
+
+    private double CalculateHitsForAllTargets(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
+      var values = row.Values;
+      if (!hits.ContainsKey(groupName)) hits.Add(groupName, new SortedList<double, double>());
+
+      var i = 0;
+      var j = 0;
+      while (i < targets.Length && j < values.Count) {
+        var current = values[j];
+        if (maximization && current.Item2 >= targets[i]
+          || !maximization && current.Item2 <= targets[i]) {
+          if (!hits[groupName].ContainsKey(current.Item1)) hits[groupName][current.Item1] = 0;
+          hits[groupName][current.Item1] += 1.0 / (groupCount * targets.Length);
+          i++;
+        } else {
+          j++;
+        }
+      }
+      if (j == values.Count) j--;
+      return values[j].Item1;
+    }
+    #endregion
+
+    #region Performance analysis by (multiple) budget(s)
+    private void UpdateResultsByCost() {
+      // necessary to reset log scale -> empty chart cannot use log scaling
+      byCostDataTable.VisualProperties.XAxisLogScale = false;
+      byCostDataTable.Rows.Clear();
+
+      var table = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(table)) return;
+
+      var selectedGroup = (string)groupComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(selectedGroup)) return;
+
+      if (budgets == null) GenerateDefaultBudgets(table);
+
+      List<Tuple<string, List<IRun>>> groupedRuns;
+      if (selectedGroup == AllRuns)
+        groupedRuns = new List<Tuple<string, List<IRun>>> {
+          Tuple.Create(AllRuns, Content.Where(r => r.Results.ContainsKey(table) && r.Visible).ToList())
+        };
+      else groupedRuns = (from r in Content
+                          where r.Results.ContainsKey(table) && r.Visible
+                          group r by r.Parameters[selectedGroup].ToString() into g
+                          select Tuple.Create(g.Key, g.ToList())).ToList();
+
+      var colorCount = 0;
+      var lineStyleCount = 0;
+      var maximization = IsMaximization();
+
+      foreach (var group in groupedRuns) {
+        var hits = new Dictionary<string, SortedList<double, double>>();
+
+        foreach (var run in group.Item2) {
+          var resultsTable = (IndexedDataTable<double>)run.Results[table];
+
+          if (eachOrAllBudgetsCheckBox.Checked) {
+            CalculateHitsForEachBudget(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
+          } else {
+            CalculateHitsForAllBudgets(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
+          }
+        }
+
+        foreach (var list in hits) {
+          var row = new IndexedDataRow<double>(list.Key) {
+            VisualProperties = {
+              ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
+              LineWidth = 2,
+              Color = colors[colorCount],
+              LineStyle = lineStyles[lineStyleCount]
+            }
+          };
+
+          var total = 0.0;
+          foreach (var h in list.Value) {
+            total += h.Value;
+            row.Values.Add(Tuple.Create(h.Key, total));
+          }
+
+          byCostDataTable.Rows.Add(row);
+        }
+        colorCount = (colorCount + 1) % colors.Length;
+        if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
+      }
+
+      byCostDataTable.VisualProperties.XAxisTitle = "Targets";
+      byCostDataTable.VisualProperties.XAxisLogScale = byCostDataTable.Rows.Count > 0 && budgetLogScalingCheckBox.Checked;
+    }
+
+    private void GenerateDefaultBudgets(string table) {
+      var min = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Min()).Min();
+      var max = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Max()).Max();
+
+      var maxMagnitude = (int)Math.Ceiling(Math.Log10(max));
+      var minMagnitude = (int)Math.Floor(Math.Log10(min));
+      if (maxMagnitude - minMagnitude >= 3) {
+        budgets = new double[maxMagnitude - minMagnitude];
+        for (var i = minMagnitude; i < maxMagnitude; i++) {
+          budgets[i - minMagnitude] = Math.Pow(10, i);
+        }
+      } else {
+        var range = max - min;
+        budgets = Enumerable.Range(0, 6).Select(x => min + (x / 5.0) * range).ToArray();
+      }
+      suppressBudgetsEvents = true;
+      budgetsTextBox.Text = string.Join(" ; ", budgets);
+      suppressBudgetsEvents = false;
+    }
+
+    private void CalculateHitsForEachBudget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
+      foreach (var b in budgets) {
+        var key = groupName + "-" + b;
+        if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
+        Tuple<double, double> prev = null;
+        foreach (var v in row.Values) {
+          if (v.Item1 >= b) {
+            // the budget may be too low to achieve any target
+            if (prev == null && v.Item1 != b) break;
+            var tgt = (prev == null || v.Item1 == b) ? v.Item2 : prev.Item2;
+            if (hits[key].ContainsKey(tgt))
+              hits[key][tgt] += 1.0 / groupCount;
+            else hits[key][tgt] = 1.0 / groupCount;
+            break;
+          }
+          prev = v;
+        }
+        if (hits[key].Count == 0) hits.Remove(key);
+      }
+    }
+
+    private void CalculateHitsForAllBudgets(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
+      var values = row.Values;
+      if (!hits.ContainsKey(groupName)) hits.Add(groupName, new SortedList<double, double>());
+
+      var i = 0;
+      var j = 0;
+      Tuple<double, double> prev = null;
+      while (i < budgets.Length && j < values.Count) {
+        var current = values[j];
+        if (current.Item1 >= budgets[i]) {
+          if (prev != null || current.Item1 == budgets[i]) {
+            var tgt = (prev == null || current.Item1 == budgets[i]) ? current.Item2 : prev.Item2;
+            if (!hits[groupName].ContainsKey(tgt)) hits[groupName][tgt] = 0;
+            hits[groupName][tgt] += 1.0 / (groupCount * budgets.Length);
+          }
+          i++;
+        } else {
+          j++;
+          prev = current;
+        }
+      }
+      var lastTgt = values.Last().Item2;
+      if (i < budgets.Length && !hits[groupName].ContainsKey(lastTgt)) hits[groupName][lastTgt] = 0;
+      while (i < budgets.Length) {
+        hits[groupName][lastTgt] += 1.0 / (groupCount * budgets.Length);
+        i++;
+      }
+    }
+    #endregion
+
     private void UpdateCaption() {
       Caption = Content != null ? Content.OptimizerName + " RLD View" : ViewAttribute.GetViewName(GetType());
@@ -342,4 +529,6 @@
     }
     private void dataTableComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (dataTableComboBox.SelectedIndex >= 0)
+        GenerateDefaultBudgets((string)dataTableComboBox.SelectedItem);
       UpdateRuns();
       SetEnabledStateOfControls();
@@ -347,7 +536,9 @@
 
     private void logScalingCheckBox_CheckedChanged(object sender, EventArgs e) {
-      combinedDataTable.VisualProperties.XAxisLogScale = logScalingCheckBox.Checked;
-    }
-
+      byTargetDataTable.VisualProperties.XAxisLogScale = byTargetDataTable.Rows.Count > 0 && targetLogScalingCheckBox.Checked;
+      byCostDataTable.VisualProperties.XAxisLogScale = byCostDataTable.Rows.Count > 0 && budgetLogScalingCheckBox.Checked;
+    }
+
+    #region Event handlers for target analysis
     private bool suppressTargetsEvents;
     private void targetsTextBox_Validating(object sender, CancelEventArgs e) {
@@ -371,37 +562,41 @@
       e.Cancel = false;
       errorProvider.SetError(targetsTextBox, null);
-      levels = targetList.ToArray();
-      UpdateRuns();
+      targets = targetList.ToArray();
+      UpdateResultsByTarget();
       SetEnabledStateOfControls();
     }
 
+    private void eachOrAllTargetCheckBox_CheckedChanged(object sender, EventArgs e) {
+      var each = eachOrAllTargetCheckBox.Checked;
+      eachOrAllTargetCheckBox.Text = each ? "each" : "all";
+      SuspendRepaint();
+      try {
+        UpdateResultsByTarget();
+      } finally { ResumeRepaint(true); }
+    }
+
     private void generateTargetsButton_Click(object sender, EventArgs e) {
+      var maximization = IsMaximization();
       decimal max = 1, min = 0, count = 10;
-      if (levels != null) {
-        max = (decimal)Math.Max(levels.First(), levels.Last());
-        min = (decimal)Math.Min(levels.First(), levels.Last());
-        count = levels.Length;
+      if (targets != null) {
+        max = (decimal)targets.Max();
+        min = (decimal)targets.Min();
+        count = targets.Length;
       } else if (Content.Count > 0 && dataTableComboBox.SelectedIndex >= 0) {
         var table = (string)dataTableComboBox.SelectedItem;
-        var worst = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item2)).First();
-        var best = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item2)).Last();
-        max = (decimal)Math.Max(best, worst);
-        min = (decimal)Math.Min(best, worst);
-        count = 10;
+        max = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item2)).Max();
+        min = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item2)).Min();
+        count = 6;
       }
       using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) {
         if (dialog.ShowDialog() == DialogResult.OK) {
           if (dialog.Values.Any()) {
-            var maximization = true;
-            if (Content.Count > 0 && Content.First().Parameters.ContainsKey("Maximization"))
-              maximization = ((BoolValue)Content.First().Parameters["Maximization"]).Value;
-
-            levels = maximization ? dialog.Values.Select(x => (double)x).ToArray()
+            targets = maximization ? dialog.Values.Select(x => (double)x).ToArray()
                                   : dialog.Values.Reverse().Select(x => (double)x).ToArray();
             suppressTargetsEvents = true;
-            targetsTextBox.Text = string.Join(" ; ", levels);
+            targetsTextBox.Text = string.Join(" ; ", targets);
             suppressTargetsEvents = false;
 
-            UpdateRuns();
+            UpdateResultsByTarget();
             SetEnabledStateOfControls();
           }
@@ -410,32 +605,92 @@
     }
 
-    private void fixedTargetButton_Click(object sender, EventArgs e) {
+    private void addTargetsAsResultButton_Click(object sender, EventArgs e) {
       var table = (string)dataTableComboBox.SelectedItem;
+      var maximization = IsMaximization();
       foreach (var run in Content) {
         if (!run.Results.ContainsKey(table)) continue;
         var resultsTable = (IndexedDataTable<double>)run.Results[table];
         var values = resultsTable.Rows.First().Values;
-        var maximization = values.First().Item2 < values.Last().Item2;
         var i = 0;
         var j = 0;
-        var current = values[j];
-        var prev = Tuple.Create(-1.0, double.NaN);
-        while (i < levels.Length) {
-          if (prev.Item2 != current.Item2
-              && (maximization && current.Item2 >= levels[i]
-              || !maximization && current.Item2 <= levels[i])) {
-            run.Results[table + ".Target" + levels[i]] = new DoubleValue(current.Item1);
+        while (i < targets.Length && j < values.Count) {
+          var current = values[j];
+          if (maximization && current.Item2 >= targets[i]
+              || !maximization && current.Item2 <= targets[i]) {
+            run.Results[table + ".Target" + targets[i]] = new DoubleValue(current.Item1);
             i++;
           } else {
             j++;
-            if (j >= values.Count) break;
-            prev = current;
-            current = values[j];
-          }
-        }
-      }
-    }
-
-    private void fixedCostButton_Click(object sender, EventArgs e) {
+          }
+        }
+      }
+    }
+    #endregion
+
+    #region Event handlers for cost analysis
+    private bool suppressBudgetsEvents;
+    private void budgetsTextBox_Validating(object sender, CancelEventArgs e) {
+      if (suppressBudgetsEvents) return;
+      var budgetStrings = budgetsTextBox.Text.Split(new[] { ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
+      var budgetList = new List<double>();
+      foreach (var ts in budgetStrings) {
+        double b;
+        if (!double.TryParse(ts, out b)) {
+          errorProvider.SetError(budgetsTextBox, "Not all targets can be parsed: " + ts);
+          e.Cancel = true;
+          return;
+        }
+        budgetList.Add(b);
+      }
+      if (budgetList.Count == 0) {
+        errorProvider.SetError(budgetsTextBox, "Give at least one target value!");
+        e.Cancel = true;
+        return;
+      }
+      e.Cancel = false;
+      errorProvider.SetError(budgetsTextBox, null);
+      budgets = budgetList.ToArray();
+      UpdateResultsByCost();
+      SetEnabledStateOfControls();
+    }
+
+    private void eachOrAllBudgetsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      var each = eachOrAllBudgetsCheckBox.Checked;
+      eachOrAllBudgetsCheckBox.Text = each ? "each" : "all";
+      SuspendRepaint();
+      try {
+        UpdateResultsByCost();
+      } finally { ResumeRepaint(true); }
+    }
+
+    private void generateBudgetsButton_Click(object sender, EventArgs e) {
+      decimal max = 1, min = 0, count = 10;
+      if (budgets != null) {
+        max = (decimal)budgets.Max();
+        min = (decimal)budgets.Min();
+        count = budgets.Length;
+      } else if (Content.Count > 0 && dataTableComboBox.SelectedIndex >= 0) {
+        var table = (string)dataTableComboBox.SelectedItem;
+        min = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item1)).Min();
+        max = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item1)).Max();
+        count = 6;
+      }
+      using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) {
+        if (dialog.ShowDialog() == DialogResult.OK) {
+          if (dialog.Values.Any()) {
+            budgets = dialog.Values.OrderBy(x => x).Select(x => (double)x).ToArray();
+
+            suppressBudgetsEvents = true;
+            budgetsTextBox.Text = string.Join(" ; ", budgets);
+            suppressBudgetsEvents = false;
+
+            UpdateResultsByCost();
+            SetEnabledStateOfControls();
+          }
+        }
+      }
+    }
+
+    private void addBudgetsAsResultButton_Click(object sender, EventArgs e) {
       var table = (string)dataTableComboBox.SelectedItem;
       var budgetStrings = budgetsTextBox.Text.Split(new[] { ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
@@ -461,25 +716,50 @@
         var i = 0;
         var j = 0;
-        var current = values[j];
-        var prev = Tuple.Create(-1.0, double.NaN);
-        while (i < budgetList.Count) {
-          if (prev.Item2 != current.Item2 && current.Item1 >= budgetList[i]) {
-            run.Results[table + ".Cost" + budgetList[i]] = new DoubleValue(double.IsNaN(prev.Item2) || current.Item1 == budgetList[i] ? current.Item2 : prev.Item2);
+        Tuple<double, double> prev = null;
+        while (i < budgetList.Count && j < values.Count) {
+          var current = values[j];
+          if (current.Item1 >= budgetList[i]) {
+            if (prev != null || current.Item1 == budgetList[i]) {
+              var tgt = (prev == null || current.Item1 == budgetList[i]) ? current.Item2 : prev.Item2;
+              run.Results[table + ".Cost" + budgetList[i]] = new DoubleValue(tgt);
+            }
             i++;
           } else {
             j++;
-            if (j >= values.Count) break;
             prev = current;
-            current = values[j];
-          }
-        }
-      }
-    }
-
-    private void allOrEachTargetCheckBox_CheckedChanged(object sender, EventArgs e) {
-      var each = allOrEachTargetCheckBox.Checked;
-      allOrEachTargetCheckBox.Text = each ? "each" : "all";
-      UpdateRuns();
-    }
+          }
+        }
+      }
+    }
+    #endregion
+
+    #region Helpers
+    // Determines if the RunCollection contains maximization or minimization runs
+    private bool IsMaximization() {
+      if (Content == null) return false;
+      if (Content.Count > 0) {
+        foreach (var run in Content.Where(x => x.Parameters.ContainsKey("Maximization")
+                                            && x.Parameters["Maximization"] is BoolValue)) {
+          if (((BoolValue)run.Parameters["Maximization"]).Value) {
+            return true;
+          } else {
+            return false;
+          }
+        }
+        if (dataTableComboBox.SelectedIndex >= 0) {
+          var selectedTable = (string)dataTableComboBox.SelectedItem;
+          foreach (var run in Content.Where(x => x.Results.ContainsKey(selectedTable))) {
+            var table = run.Results[selectedTable] as IndexedDataTable<double>;
+            if (table == null) continue;
+            var firstRowValues = table.Rows.First().Values;
+            if (firstRowValues.Count < 2) continue;
+            return firstRowValues[0].Item2 < firstRowValues[firstRowValues.Count - 1].Item2;
+          }
+        }
+      }
+      // assume minimization by default
+      return false;
+    }
+    #endregion
   }
 }
