Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalParameterView.Designer.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalParameterView.Designer.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalParameterView.Designer.cs	(revision 16133)
@@ -0,0 +1,175 @@
+﻿namespace HeuristicLab.GoalSeeking.Views {
+  partial class GoalSeekingTargetView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.groupBox = new System.Windows.Forms.GroupBox();
+      this.activeCheckBox = new System.Windows.Forms.CheckBox();
+      this.stepTextBox = new System.Windows.Forms.TextBox();
+      this.varianceTextBox = new System.Windows.Forms.TextBox();
+      this.weightTextBox = new System.Windows.Forms.TextBox();
+      this.goalTextBox = new System.Windows.Forms.TextBox();
+      this.stepLabel = new System.Windows.Forms.Label();
+      this.varianceLabel = new System.Windows.Forms.Label();
+      this.weightLabel = new System.Windows.Forms.Label();
+      this.goalLabel = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.groupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // groupBox
+      // 
+      this.groupBox.Controls.Add(this.activeCheckBox);
+      this.groupBox.Controls.Add(this.stepTextBox);
+      this.groupBox.Controls.Add(this.varianceTextBox);
+      this.groupBox.Controls.Add(this.weightTextBox);
+      this.groupBox.Controls.Add(this.goalTextBox);
+      this.groupBox.Controls.Add(this.stepLabel);
+      this.groupBox.Controls.Add(this.varianceLabel);
+      this.groupBox.Controls.Add(this.weightLabel);
+      this.groupBox.Controls.Add(this.goalLabel);
+      this.groupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.groupBox.Location = new System.Drawing.Point(0, 0);
+      this.groupBox.Name = "groupBox";
+      this.groupBox.Size = new System.Drawing.Size(205, 148);
+      this.groupBox.TabIndex = 0;
+      this.groupBox.TabStop = false;
+      this.groupBox.Text = "Target";
+      // 
+      // activeCheckBox
+      // 
+      this.activeCheckBox.AutoSize = true;
+      this.activeCheckBox.Location = new System.Drawing.Point(6, 19);
+      this.activeCheckBox.Name = "activeCheckBox";
+      this.activeCheckBox.Size = new System.Drawing.Size(56, 17);
+      this.activeCheckBox.TabIndex = 2;
+      this.activeCheckBox.Text = "Active";
+      this.activeCheckBox.UseVisualStyleBackColor = true;
+      this.activeCheckBox.CheckedChanged += new System.EventHandler(this.activeCheckBox_CheckedChanged);
+      // 
+      // stepTextBox
+      // 
+      this.stepTextBox.Location = new System.Drawing.Point(100, 122);
+      this.stepTextBox.Name = "stepTextBox";
+      this.stepTextBox.Size = new System.Drawing.Size(100, 20);
+      this.stepTextBox.TabIndex = 1;
+      this.stepTextBox.TextChanged += new System.EventHandler(this.stepTextBox_TextChanged);
+      // 
+      // varianceTextBox
+      // 
+      this.varianceTextBox.Location = new System.Drawing.Point(100, 96);
+      this.varianceTextBox.Name = "varianceTextBox";
+      this.varianceTextBox.Size = new System.Drawing.Size(100, 20);
+      this.varianceTextBox.TabIndex = 1;
+      this.varianceTextBox.TextChanged += new System.EventHandler(this.varianceTextBox_TextChanged);
+      // 
+      // weightTextBox
+      // 
+      this.weightTextBox.Location = new System.Drawing.Point(100, 70);
+      this.weightTextBox.Name = "weightTextBox";
+      this.weightTextBox.Size = new System.Drawing.Size(100, 20);
+      this.weightTextBox.TabIndex = 1;
+      this.weightTextBox.TextChanged += new System.EventHandler(this.weightTextBox_TextChanged);
+      this.weightTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.weightTextBox.Validated += new System.EventHandler(this.TextBoxValidated);
+      // 
+      // goalTextBox
+      // 
+      this.goalTextBox.Location = new System.Drawing.Point(100, 44);
+      this.goalTextBox.Name = "goalTextBox";
+      this.goalTextBox.Size = new System.Drawing.Size(100, 20);
+      this.goalTextBox.TabIndex = 1;
+      this.goalTextBox.TextChanged += new System.EventHandler(this.goalTextBox_TextChanged);
+      this.goalTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.goalTextBox.Validated += new System.EventHandler(this.TextBoxValidated);
+      // 
+      // stepLabel
+      // 
+      this.stepLabel.AutoSize = true;
+      this.stepLabel.Location = new System.Drawing.Point(6, 125);
+      this.stepLabel.Name = "stepLabel";
+      this.stepLabel.Size = new System.Drawing.Size(29, 13);
+      this.stepLabel.TabIndex = 0;
+      this.stepLabel.Text = "Step";
+      // 
+      // varianceLabel
+      // 
+      this.varianceLabel.AutoSize = true;
+      this.varianceLabel.Location = new System.Drawing.Point(6, 99);
+      this.varianceLabel.Name = "varianceLabel";
+      this.varianceLabel.Size = new System.Drawing.Size(49, 13);
+      this.varianceLabel.TabIndex = 0;
+      this.varianceLabel.Text = "Variance";
+      // 
+      // weightLabel
+      // 
+      this.weightLabel.AutoSize = true;
+      this.weightLabel.Location = new System.Drawing.Point(6, 73);
+      this.weightLabel.Name = "weightLabel";
+      this.weightLabel.Size = new System.Drawing.Size(41, 13);
+      this.weightLabel.TabIndex = 0;
+      this.weightLabel.Text = "Weight";
+      // 
+      // goalLabel
+      // 
+      this.goalLabel.AutoSize = true;
+      this.goalLabel.Location = new System.Drawing.Point(6, 47);
+      this.goalLabel.Name = "goalLabel";
+      this.goalLabel.Size = new System.Drawing.Size(29, 13);
+      this.goalLabel.TabIndex = 0;
+      this.goalLabel.Text = "Goal";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.ContainerControl = this;
+      // 
+      // GoalSeekingTargetView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.groupBox);
+      this.Name = "GoalSeekingTargetView";
+      this.Size = new System.Drawing.Size(205, 148);
+      this.groupBox.ResumeLayout(false);
+      this.groupBox.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox groupBox;
+    private System.Windows.Forms.Label goalLabel;
+    private System.Windows.Forms.Label stepLabel;
+    private System.Windows.Forms.Label varianceLabel;
+    private System.Windows.Forms.Label weightLabel;
+    private System.Windows.Forms.TextBox stepTextBox;
+    private System.Windows.Forms.TextBox varianceTextBox;
+    private System.Windows.Forms.TextBox weightTextBox;
+    private System.Windows.Forms.TextBox goalTextBox;
+    private System.Windows.Forms.CheckBox activeCheckBox;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalParameterView.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalParameterView.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalParameterView.cs	(revision 16133)
@@ -0,0 +1,115 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.GoalSeeking.Views {
+  [View("GoalSeekingTarget View", "")]
+  [Content(typeof(GoalParameter), true)]
+  public partial class GoalSeekingTargetView : AsynchronousContentView {
+    public new GoalParameter Content {
+      get { return (GoalParameter)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public GoalSeekingTargetView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        groupBox.Text = Content.Name;
+        goalTextBox.Text = Content.Goal.ToString(CultureInfo.CurrentCulture);
+        weightTextBox.Text = Content.Weight.ToString(CultureInfo.CurrentCulture);
+        varianceTextBox.Text = Content.Variance.ToString(CultureInfo.CurrentCulture);
+        stepTextBox.Text = Content.Step.ToString(CultureInfo.CurrentCulture);
+        activeCheckBox.Checked = Content.Active;
+        Content.Changed += Content_Changed;
+      }
+    }
+
+    private void Content_Changed(object sender, EventArgs args) {
+      groupBox.Text = Content.Name;
+      goalTextBox.Text = Content.Goal.ToString(CultureInfo.CurrentCulture);
+      weightTextBox.Text = Content.Weight.ToString(CultureInfo.CurrentCulture);
+      varianceTextBox.Text = Content.Variance.ToString(CultureInfo.CurrentCulture);
+      stepTextBox.Text = Content.Step.ToString(CultureInfo.CurrentCulture);
+      activeCheckBox.Checked = Content.Active;
+    }
+
+    #region event handlers
+    private void TextBoxValidating(object sender, CancelEventArgs e) {
+      double v;
+      string errorMsg = "Could not parse the entered value. Please input a real number.";
+      var tb = (TextBox)sender;
+      if (!double.TryParse(tb.Text, out v)) {
+        e.Cancel = true;
+        tb.Select(0, tb.Text.Length);
+
+        // Set the ErrorProvider error with the text to display. 
+        this.errorProvider.SetError(tb, errorMsg);
+        errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;
+        errorProvider.SetIconPadding(tb, -20);
+      }
+    }
+
+    private void TextBoxValidated(object sender, EventArgs e) {
+      var tb = (TextBox)sender;
+      errorProvider.SetError(tb, string.Empty);
+    }
+
+    private void activeCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      Content.Active = activeCheckBox.Checked;
+      goalTextBox.Enabled = weightTextBox.Enabled = stepTextBox.Enabled = varianceTextBox.Enabled = Content.Active;
+    }
+
+    private void goalTextBox_TextChanged(object sender, EventArgs e) {
+      double goal;
+      if (double.TryParse(goalTextBox.Text, out goal))
+        Content.Goal = goal;
+    }
+
+    private void weightTextBox_TextChanged(object sender, EventArgs e) {
+      double weight;
+      if (double.TryParse(weightTextBox.Text, out weight))
+        Content.Weight = weight;
+    }
+
+    private void varianceTextBox_TextChanged(object sender, EventArgs e) {
+      double variance;
+      if (double.TryParse(varianceTextBox.Text, out variance))
+        Content.Variance = variance;
+    }
+
+    private void stepTextBox_TextChanged(object sender, System.EventArgs e) {
+      double step;
+      if (double.TryParse(stepTextBox.Text, out step))
+        Content.Step = step;
+    }
+    #endregion
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingOptimizerView.Designer.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingOptimizerView.Designer.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingOptimizerView.Designer.cs	(revision 16133)
@@ -0,0 +1,249 @@
+﻿namespace HeuristicLab.GoalSeeking {
+  partial class GoalSeekingOptimizerView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.problemTab = new System.Windows.Forms.TabPage();
+      this.problemViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.algorithmTab = new System.Windows.Forms.TabPage();
+      this.algorithmViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.dataTab = new System.Windows.Forms.TabPage();
+      this.dataViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.resultsTab = new System.Windows.Forms.TabPage();
+      this.resultsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.problemTab.SuspendLayout();
+      this.algorithmTab.SuspendLayout();
+      this.dataTab.SuspendLayout();
+      this.resultsTab.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // startButton
+      // 
+      this.startButton.Location = new System.Drawing.Point(6, 636);
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Optimizer");
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Location = new System.Drawing.Point(936, 640);
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Location = new System.Drawing.Point(847, 643);
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Location = new System.Drawing.Point(36, 636);
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Optimizer");
+      // 
+      // stopButton
+      // 
+      this.stopButton.Location = new System.Drawing.Point(66, 636);
+      this.toolTip.SetToolTip(this.stopButton, "Stop Optimizer");
+      // 
+      // resetButton
+      // 
+      this.resetButton.Location = new System.Drawing.Point(96, 636);
+      this.toolTip.SetToolTip(this.resetButton, "Reset Optimizer");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Size = new System.Drawing.Size(1008, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(995, 3);
+      // 
+      // 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) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Controls.Add(this.problemTab);
+      this.tabControl.Controls.Add(this.algorithmTab);
+      this.tabControl.Controls.Add(this.dataTab);
+      this.tabControl.Controls.Add(this.resultsTab);
+      this.tabControl.Location = new System.Drawing.Point(3, 26);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(1070, 604);
+      this.tabControl.TabIndex = 0;
+      // 
+      // problemTab
+      // 
+      this.problemTab.AllowDrop = true;
+      this.problemTab.Controls.Add(this.problemViewHost);
+      this.problemTab.Location = new System.Drawing.Point(4, 22);
+      this.problemTab.Name = "problemTab";
+      this.problemTab.Padding = new System.Windows.Forms.Padding(3);
+      this.problemTab.Size = new System.Drawing.Size(527, 259);
+      this.problemTab.TabIndex = 0;
+      this.problemTab.Text = "Problem";
+      this.problemTab.UseVisualStyleBackColor = true;
+      this.problemTab.DragDrop += new System.Windows.Forms.DragEventHandler(this.problemTab_DragDrop);
+      this.problemTab.DragEnter += new System.Windows.Forms.DragEventHandler(this.problemTab_DragEnter);
+      // 
+      // problemViewHost
+      // 
+      this.problemViewHost.AllowDrop = true;
+      this.problemViewHost.BackColor = System.Drawing.Color.Transparent;
+      this.problemViewHost.Caption = "View";
+      this.problemViewHost.Content = null;
+      this.problemViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.problemViewHost.Enabled = false;
+      this.problemViewHost.Location = new System.Drawing.Point(3, 3);
+      this.problemViewHost.Name = "problemViewHost";
+      this.problemViewHost.ReadOnly = false;
+      this.problemViewHost.Size = new System.Drawing.Size(521, 253);
+      this.problemViewHost.TabIndex = 0;
+      this.problemViewHost.ViewsLabelVisible = true;
+      this.problemViewHost.ViewType = null;
+      // 
+      // algorithmTab
+      // 
+      this.algorithmTab.AllowDrop = true;
+      this.algorithmTab.Controls.Add(this.algorithmViewHost);
+      this.algorithmTab.Location = new System.Drawing.Point(4, 22);
+      this.algorithmTab.Name = "algorithmTab";
+      this.algorithmTab.Padding = new System.Windows.Forms.Padding(3);
+      this.algorithmTab.Size = new System.Drawing.Size(950, 554);
+      this.algorithmTab.TabIndex = 1;
+      this.algorithmTab.Text = "Algorithm";
+      this.algorithmTab.UseVisualStyleBackColor = true;
+      this.algorithmTab.DragDrop += new System.Windows.Forms.DragEventHandler(this.algorithmTab_DragDrop);
+      this.algorithmTab.DragEnter += new System.Windows.Forms.DragEventHandler(this.algorithmTab_DragEnter);
+      // 
+      // algorithmViewHost
+      // 
+      this.algorithmViewHost.Caption = "View";
+      this.algorithmViewHost.Content = null;
+      this.algorithmViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.algorithmViewHost.Enabled = false;
+      this.algorithmViewHost.Location = new System.Drawing.Point(3, 3);
+      this.algorithmViewHost.Name = "algorithmViewHost";
+      this.algorithmViewHost.ReadOnly = false;
+      this.algorithmViewHost.Size = new System.Drawing.Size(944, 548);
+      this.algorithmViewHost.TabIndex = 0;
+      this.algorithmViewHost.ViewsLabelVisible = true;
+      this.algorithmViewHost.ViewType = null;
+      // 
+      // dataTab
+      // 
+      this.dataTab.AllowDrop = true;
+      this.dataTab.Controls.Add(this.dataViewHost);
+      this.dataTab.Location = new System.Drawing.Point(4, 22);
+      this.dataTab.Name = "dataTab";
+      this.dataTab.Padding = new System.Windows.Forms.Padding(3);
+      this.dataTab.Size = new System.Drawing.Size(1062, 578);
+      this.dataTab.TabIndex = 2;
+      this.dataTab.Text = "Data";
+      this.dataTab.UseVisualStyleBackColor = true;
+      this.dataTab.DragDrop += new System.Windows.Forms.DragEventHandler(this.dataTab_DragDrop);
+      this.dataTab.DragEnter += new System.Windows.Forms.DragEventHandler(this.dataTab_DragEnter);
+      // 
+      // dataViewHost
+      // 
+      this.dataViewHost.AllowDrop = true;
+      this.dataViewHost.Caption = "View";
+      this.dataViewHost.Content = null;
+      this.dataViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.dataViewHost.Enabled = false;
+      this.dataViewHost.Location = new System.Drawing.Point(3, 3);
+      this.dataViewHost.Name = "dataViewHost";
+      this.dataViewHost.ReadOnly = false;
+      this.dataViewHost.Size = new System.Drawing.Size(1056, 572);
+      this.dataViewHost.TabIndex = 0;
+      this.dataViewHost.ViewsLabelVisible = true;
+      this.dataViewHost.ViewType = null;
+      // 
+      // resultsTab
+      // 
+      this.resultsTab.Controls.Add(this.resultsViewHost);
+      this.resultsTab.Location = new System.Drawing.Point(4, 22);
+      this.resultsTab.Name = "resultsTab";
+      this.resultsTab.Size = new System.Drawing.Size(950, 554);
+      this.resultsTab.TabIndex = 3;
+      this.resultsTab.Text = "Results";
+      this.resultsTab.UseVisualStyleBackColor = true;
+      // 
+      // resultsViewHost
+      // 
+      this.resultsViewHost.Caption = "View";
+      this.resultsViewHost.Content = null;
+      this.resultsViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.resultsViewHost.Enabled = false;
+      this.resultsViewHost.Location = new System.Drawing.Point(0, 0);
+      this.resultsViewHost.Name = "resultsViewHost";
+      this.resultsViewHost.ReadOnly = false;
+      this.resultsViewHost.Size = new System.Drawing.Size(950, 554);
+      this.resultsViewHost.TabIndex = 0;
+      this.resultsViewHost.ViewsLabelVisible = true;
+      this.resultsViewHost.ViewType = null;
+      // 
+      // GoalSeekingOptimizerView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl);
+      this.Name = "GoalSeekingOptimizerView";
+      this.Size = new System.Drawing.Size(1076, 663);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.resetButton, 0);
+      this.Controls.SetChildIndex(this.stopButton, 0);
+      this.Controls.SetChildIndex(this.pauseButton, 0);
+      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.problemTab.ResumeLayout(false);
+      this.algorithmTab.ResumeLayout(false);
+      this.dataTab.ResumeLayout(false);
+      this.resultsTab.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage problemTab;
+    private System.Windows.Forms.TabPage algorithmTab;
+    private System.Windows.Forms.TabPage dataTab;
+    private System.Windows.Forms.TabPage resultsTab;
+    private MainForm.WindowsForms.ViewHost problemViewHost;
+    private MainForm.WindowsForms.ViewHost algorithmViewHost;
+    private MainForm.WindowsForms.ViewHost dataViewHost;
+    private MainForm.WindowsForms.ViewHost resultsViewHost;
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingOptimizerView.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingOptimizerView.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingOptimizerView.cs	(revision 16133)
@@ -0,0 +1,143 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Views;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.GoalSeeking {
+  [View("GoalSeekingOptimizer View", "")]
+  [Content(typeof(GoalSeekingOptimizer), true)]
+  public partial class GoalSeekingOptimizerView : IOptimizerView {
+    public GoalSeekingOptimizerView() {
+      InitializeComponent();
+      Content = new GoalSeekingOptimizer();
+    }
+
+    public new GoalSeekingOptimizer Content {
+      get { return (GoalSeekingOptimizer)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null)
+        return;
+
+      if (Content.Optimizer != null)
+        algorithmViewHost.Content = Content.Optimizer;
+
+      if (Content.Problem != null)
+        problemViewHost.Content = Content.Problem;
+
+      if (Content.ProblemData != null)
+        dataViewHost.Content = Content.ProblemData;
+
+      if (Content.Results != null)
+        resultsViewHost.Content = Content.Results;
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.AlgorithmChanged += (o, e) => { algorithmViewHost.Content = Content.Optimizer; };
+      Content.ProblemChanged += (o, e) => { problemViewHost.Content = Content.Problem; };
+      Content.ProblemDataChanged += (o, e) => { dataViewHost.Content = Content.ProblemData; };
+      Content.ResultsChanged += (o, e) => { resultsViewHost.Content = Content.Results; };
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+    }
+
+    #region event handlers
+    private void problemTab_DragDrop(object sender, DragEventArgs e) {
+      if (e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat)) {
+        try {
+          Content.Problem = (IGoalSeekingProblem)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+          problemViewHost.Content = Content.Problem;
+        }
+        catch (Exception ex) {
+          MessageBox.Show(ex.Message, "Set problem", MessageBoxButtons.OK, MessageBoxIcon.Error);
+        }
+      }
+    }
+
+    private void problemTab_DragEnter(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat))
+        return;
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+
+      if (data is IGoalSeekingProblem)
+        e.Effect = DragDropEffects.Copy;
+    }
+
+    private void algorithmTab_DragDrop(object sender, DragEventArgs e) {
+      if (e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat)) {
+        try {
+          Content.Optimizer = (IAlgorithm)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+          algorithmViewHost.Content = Content.Optimizer;
+        }
+        catch (Exception ex) {
+          MessageBox.Show(ex.Message, "Set algorithm", MessageBoxButtons.OK, MessageBoxIcon.Error);
+        }
+      }
+    }
+
+    private void algorithmTab_DragEnter(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat))
+        return;
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (data is IAlgorithm)
+        e.Effect = DragDropEffects.Copy;
+    }
+    #endregion
+
+    private void dataTab_DragDrop(object sender, DragEventArgs e) {
+      if (e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat)) {
+        try {
+          Content.ProblemData = (IRegressionProblemData)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+          dataViewHost.Content = Content.ProblemData;
+        }
+        catch (Exception ex) {
+          // provide some information to the user
+          MessageBox.Show(ex.Message, "Set problem data", MessageBoxButtons.OK, MessageBoxIcon.Error);
+        }
+      }
+    }
+
+    private void dataTab_DragEnter(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat))
+        return;
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (data is IRegressionProblemData)
+        e.Effect = DragDropEffects.Copy;
+    }
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingProblem.Views.csproj
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingProblem.Views.csproj	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/GoalSeekingProblem.Views.csproj	(revision 16133)
@@ -0,0 +1,135 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GoalSeekingProblem.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.GoalSeekingProblem.Views-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <LangVersion>4</LangVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec" />
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="GoalSeekingOptimizerView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="GoalSeekingOptimizerView.Designer.cs">
+      <DependentUpon>GoalSeekingOptimizerView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="InputParameterView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="InputParameterView.Designer.cs">
+      <DependentUpon>InputParameterView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="GoalParameterView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="GoalParameterView.Designer.cs">
+      <DependentUpon>GoalParameterView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.GoalSeekingProblem\3.4\GoalSeekingProblem.csproj">
+      <Project>{79271bc8-4446-40e2-bb89-9be4e17174fe}</Project>
+      <Name>GoalSeekingProblem</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/InputParameterView.Designer.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/InputParameterView.Designer.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/InputParameterView.Designer.cs	(revision 16133)
@@ -0,0 +1,180 @@
+﻿namespace HeuristicLab.GoalSeeking.Views {
+  partial class GoalSeekingParameterView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.groupBox = new System.Windows.Forms.GroupBox();
+      this.activeCheckBox = new System.Windows.Forms.CheckBox();
+      this.valueTextBox = new System.Windows.Forms.TextBox();
+      this.stepTextBox = new System.Windows.Forms.TextBox();
+      this.maxTextBox = new System.Windows.Forms.TextBox();
+      this.valueLabel = new System.Windows.Forms.Label();
+      this.minTextBox = new System.Windows.Forms.TextBox();
+      this.stepLabel = new System.Windows.Forms.Label();
+      this.maximumLabel = new System.Windows.Forms.Label();
+      this.minimumLabel = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.groupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // groupBox
+      // 
+      this.groupBox.Controls.Add(this.activeCheckBox);
+      this.groupBox.Controls.Add(this.valueTextBox);
+      this.groupBox.Controls.Add(this.stepTextBox);
+      this.groupBox.Controls.Add(this.maxTextBox);
+      this.groupBox.Controls.Add(this.valueLabel);
+      this.groupBox.Controls.Add(this.minTextBox);
+      this.groupBox.Controls.Add(this.stepLabel);
+      this.groupBox.Controls.Add(this.maximumLabel);
+      this.groupBox.Controls.Add(this.minimumLabel);
+      this.groupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.groupBox.Location = new System.Drawing.Point(0, 0);
+      this.groupBox.Name = "groupBox";
+      this.groupBox.Size = new System.Drawing.Size(204, 149);
+      this.groupBox.TabIndex = 1;
+      this.groupBox.TabStop = false;
+      this.groupBox.Text = "Parameter";
+      // 
+      // activeCheckBox
+      // 
+      this.activeCheckBox.AutoSize = true;
+      this.activeCheckBox.Location = new System.Drawing.Point(6, 19);
+      this.activeCheckBox.Name = "activeCheckBox";
+      this.activeCheckBox.Size = new System.Drawing.Size(56, 17);
+      this.activeCheckBox.TabIndex = 2;
+      this.activeCheckBox.Text = "Active";
+      this.activeCheckBox.UseVisualStyleBackColor = true;
+      this.activeCheckBox.CheckedChanged += new System.EventHandler(this.activeCheckBox_CheckedChanged);
+      // 
+      // valueTextBox
+      // 
+      this.valueTextBox.Location = new System.Drawing.Point(98, 122);
+      this.valueTextBox.Name = "valueTextBox";
+      this.valueTextBox.Size = new System.Drawing.Size(100, 20);
+      this.valueTextBox.TabIndex = 1;
+      this.valueTextBox.TextChanged += new System.EventHandler(this.valueTextBox_TextChanged);
+      this.valueTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.valueTextBox.Validated += new System.EventHandler(this.TextBoxValidated);
+      // 
+      // stepTextBox
+      // 
+      this.stepTextBox.Location = new System.Drawing.Point(98, 96);
+      this.stepTextBox.Name = "stepTextBox";
+      this.stepTextBox.Size = new System.Drawing.Size(100, 20);
+      this.stepTextBox.TabIndex = 1;
+      this.stepTextBox.TextChanged += new System.EventHandler(this.stepTextBox_TextChanged);
+      this.stepTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.stepTextBox.Validated += new System.EventHandler(this.TextBoxValidated);
+      // 
+      // maxTextBox
+      // 
+      this.maxTextBox.Location = new System.Drawing.Point(98, 70);
+      this.maxTextBox.Name = "maxTextBox";
+      this.maxTextBox.Size = new System.Drawing.Size(100, 20);
+      this.maxTextBox.TabIndex = 1;
+      this.maxTextBox.TextChanged += new System.EventHandler(this.maxTextBox_TextChanged);
+      this.maxTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.maxTextBox.Validated += new System.EventHandler(this.TextBoxValidated);
+      // 
+      // valueLabel
+      // 
+      this.valueLabel.AutoSize = true;
+      this.valueLabel.Location = new System.Drawing.Point(4, 125);
+      this.valueLabel.Name = "valueLabel";
+      this.valueLabel.Size = new System.Drawing.Size(34, 13);
+      this.valueLabel.TabIndex = 0;
+      this.valueLabel.Text = "Value";
+      // 
+      // minTextBox
+      // 
+      this.minTextBox.Location = new System.Drawing.Point(98, 44);
+      this.minTextBox.Name = "minTextBox";
+      this.minTextBox.Size = new System.Drawing.Size(100, 20);
+      this.minTextBox.TabIndex = 1;
+      this.minTextBox.TextChanged += new System.EventHandler(this.minTextBox_TextChanged);
+      this.minTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.minTextBox.Validated += new System.EventHandler(this.TextBoxValidated);
+      // 
+      // stepLabel
+      // 
+      this.stepLabel.AutoSize = true;
+      this.stepLabel.Location = new System.Drawing.Point(4, 99);
+      this.stepLabel.Name = "stepLabel";
+      this.stepLabel.Size = new System.Drawing.Size(29, 13);
+      this.stepLabel.TabIndex = 0;
+      this.stepLabel.Text = "Step";
+      // 
+      // maximumLabel
+      // 
+      this.maximumLabel.AutoSize = true;
+      this.maximumLabel.Location = new System.Drawing.Point(4, 73);
+      this.maximumLabel.Name = "maximumLabel";
+      this.maximumLabel.Size = new System.Drawing.Size(51, 13);
+      this.maximumLabel.TabIndex = 0;
+      this.maximumLabel.Text = "Maximum";
+      // 
+      // minimumLabel
+      // 
+      this.minimumLabel.AutoSize = true;
+      this.minimumLabel.Location = new System.Drawing.Point(4, 47);
+      this.minimumLabel.Name = "minimumLabel";
+      this.minimumLabel.Size = new System.Drawing.Size(48, 13);
+      this.minimumLabel.TabIndex = 0;
+      this.minimumLabel.Text = "Minimum";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.ContainerControl = this;
+      // 
+      // GoalSeekingParameterView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.groupBox);
+      this.Name = "GoalSeekingParameterView";
+      this.Size = new System.Drawing.Size(204, 149);
+      this.groupBox.ResumeLayout(false);
+      this.groupBox.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox groupBox;
+    private System.Windows.Forms.CheckBox activeCheckBox;
+    private System.Windows.Forms.TextBox stepTextBox;
+    private System.Windows.Forms.TextBox maxTextBox;
+    private System.Windows.Forms.TextBox minTextBox;
+    private System.Windows.Forms.Label stepLabel;
+    private System.Windows.Forms.Label maximumLabel;
+    private System.Windows.Forms.Label minimumLabel;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.TextBox valueTextBox;
+    private System.Windows.Forms.Label valueLabel;
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/InputParameterView.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/InputParameterView.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/InputParameterView.cs	(revision 16133)
@@ -0,0 +1,116 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.GoalSeeking.Views {
+  [View("GoalSeekingParameter View", "")]
+  [Content(typeof(InputParameter), true)]
+  public partial class GoalSeekingParameterView : AsynchronousContentView {
+    public new InputParameter Content {
+      get { return (InputParameter)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public GoalSeekingParameterView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        groupBox.Text = Content.Name;
+        minTextBox.Text = Content.Min.ToString(CultureInfo.CurrentCulture);
+        maxTextBox.Text = Content.Max.ToString(CultureInfo.CurrentCulture);
+        stepTextBox.Text = Content.Step.ToString(CultureInfo.CurrentCulture);
+        valueTextBox.Text = Content.Value.ToString(CultureInfo.CurrentCulture);
+        activeCheckBox.Checked = Content.Active;
+        Content.Changed += Content_Changed;
+      }
+    }
+
+    private void Content_Changed(object sender, EventArgs args) {
+      groupBox.Text = Content.Name;
+      minTextBox.Text = Content.Min.ToString(CultureInfo.CurrentCulture);
+      maxTextBox.Text = Content.Max.ToString(CultureInfo.CurrentCulture);
+      stepTextBox.Text = Content.Step.ToString(CultureInfo.CurrentCulture);
+      valueTextBox.Text = Content.Value.ToString(CultureInfo.CurrentCulture);
+      activeCheckBox.Checked = Content.Active;
+    }
+
+    #region event handlers
+    private void TextBoxValidating(object sender, CancelEventArgs e) {
+      double v;
+      string errorMsg = "Could not parse the entered value. Please input a real number.";
+      var tb = (TextBox)sender;
+      if (!double.TryParse(tb.Text, out v)) {
+        e.Cancel = true;
+        tb.Select(0, tb.Text.Length);
+
+        // Set the ErrorProvider error with the text to display. 
+        this.errorProvider.SetError(tb, errorMsg);
+        errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;
+        errorProvider.SetIconPadding(tb, -20);
+      }
+    }
+
+    private void TextBoxValidated(object sender, EventArgs e) {
+      var tb = (TextBox)sender;
+      errorProvider.SetError(tb, string.Empty);
+    }
+    #endregion
+
+    private void minTextBox_TextChanged(object sender, EventArgs e) {
+      double min;
+      if (double.TryParse(minTextBox.Text, out min))
+        Content.Min = min;
+    }
+
+    private void maxTextBox_TextChanged(object sender, EventArgs e) {
+      double max;
+      if (double.TryParse(maxTextBox.Text, out max))
+        Content.Max = max;
+    }
+
+    private void stepTextBox_TextChanged(object sender, EventArgs e) {
+      double step;
+      if (double.TryParse(stepTextBox.Text, out step))
+        Content.Step = step;
+    }
+
+    private void valueTextBox_TextChanged(object sender, EventArgs e) {
+      double value;
+      if (double.TryParse(valueTextBox.Text, out value))
+        Content.Value = value;
+    }
+
+    private void activeCheckBox_CheckedChanged(object sender, EventArgs e) {
+      Content.Active = activeCheckBox.Checked;
+      minTextBox.Enabled = maxTextBox.Enabled = stepTextBox.Enabled = Content.Active;
+      valueTextBox.Enabled = !Content.Active;
+    }
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Plugin.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Plugin.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Plugin.cs	(revision 16133)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GoalSeekingProblem.Views {
+  [Plugin("HeuristicLab.GoalSeekingProblem.Views", "3.4.0.0")]
+  [PluginFile("HeuristicLab.GoalSeekingProblem.Views-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+
+  public class HeuristicLabProcessParameterOptimizationPlugin : PluginBase {
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Plugin.cs.frame
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Plugin.cs.frame	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Plugin.cs.frame	(revision 16133)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GoalSeekingProblem.Views {
+  [Plugin("HeuristicLab.GoalSeekingProblem.Views", "3.4.0.0")]
+  [PluginFile("HeuristicLab.GoalSeekingProblem.Views-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+
+  public class HeuristicLabProcessParameterOptimizationPlugin : PluginBase {
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/PreBuildEvent.cmd
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/PreBuildEvent.cmd	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/PreBuildEvent.cmd	(revision 16133)
@@ -0,0 +1,11 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+GOTO Done
+
+:Error_Handling
+ECHO There was an error while running subwcrev. Please verify that the *.cs.frame files have been correctly converted to *.cs files, otherwise HeuristicLab won't build. 
+exit 0
+
+:Done
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Properties/AssemblyInfo.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Properties/AssemblyInfo.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.Views/3.4/Properties/AssemblyInfo.cs	(revision 16133)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GoalSeekingProblem.Views")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GoalSeekingProblem.Views")]
+[assembly: AssemblyCopyright("Copyright ©  2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b0cbff1b-6a06-4dda-b622-e847b8adc908")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.sln
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.sln	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem.sln	(revision 16133)
@@ -0,0 +1,48 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoalSeekingProblem", "HeuristicLab.GoalSeekingProblem\3.4\GoalSeekingProblem.csproj", "{79271BC8-4446-40E2-BB89-9BE4E17174FE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoalSeekingProblem.Views", "HeuristicLab.GoalSeekingProblem.Views\3.4\GoalSeekingProblem.Views.csproj", "{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Debug|x64.ActiveCfg = Debug|x64
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Debug|x64.Build.0 = Debug|x64
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Debug|x86.ActiveCfg = Debug|x86
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Debug|x86.Build.0 = Debug|x86
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Release|x64.ActiveCfg = Release|x64
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Release|x64.Build.0 = Release|x64
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Release|x86.ActiveCfg = Release|x86
+		{79271BC8-4446-40E2-BB89-9BE4E17174FE}.Release|x86.Build.0 = Release|x86
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Debug|x64.Build.0 = Debug|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Debug|x86.Build.0 = Debug|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Release|x64.ActiveCfg = Release|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Release|x64.Build.0 = Release|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Release|x86.ActiveCfg = Release|Any CPU
+		{B0CBFF1B-6A06-4DDA-B622-E847B8ADC908}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Analyzers/BestSolutionAnalyzer.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Analyzers/BestSolutionAnalyzer.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Analyzers/BestSolutionAnalyzer.cs	(revision 16133)
@@ -0,0 +1,150 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.GoalSeeking {
+  [StorableClass]
+  [Item("BestSolutionAnalyzer", "An analyzer which identifies the best solution from the SingleObjectiveProcessParameterOptimizationProblem")]
+  public class BestSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    private const string RowParameterName = "Row";
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string QualityParameterName = "Quality";
+    private const string MaximizationParameterName = "Maximization";
+
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
+    }
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+    }
+    public IFixedValueParameter<StringValue> BestSolutionResultNameParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters["BestSolution ResultName"]; }
+    }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ILookupParameter<IntValue> RowParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[RowParameterName]; }
+    }
+    public ILookupParameter<IRegressionProblemData> ProblemDataParameter {
+      get { return (ILookupParameter<IRegressionProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+
+    public BoolValue Maximization {
+      get { return MaximizationParameter.ActualValue; }
+    }
+
+    public ItemArray<DoubleValue> Quality {
+      get { return QualityParameter.ActualValue; }
+    }
+
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+
+    public string BestSolutionResultName {
+      get { return BestSolutionResultNameParameter.Value.Value; }
+      set { BestSolutionResultNameParameter.Value.Value = value; }
+    }
+
+    public BestSolutionAnalyzer() {
+      Parameters.Add(new FixedValueParameter<StringValue>("BestSolution ResultName", "The name of the result for storing the best solution.", new StringValue("Best Solution")));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution."));
+      Parameters.Add(new LookupParameter<IntValue>(RowParameterName, "The current row"));
+      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName, "The problem data"));
+      Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "Specifies whether the problem is a minimization or a maximization problem."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName, "The qualities of the individuals in the population"));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection"));
+    }
+
+    protected BestSolutionAnalyzer(BestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestSolutionAnalyzer(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected BestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(MaximizationParameterName))
+        Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "Specifies whether the problem is a minimization or a maximization problem."));
+      if (!Parameters.ContainsKey(QualityParameterName))
+        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName, "The qualities of the individuals in the population"));
+      if (!Parameters.ContainsKey("Results"))
+        Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection"));
+    }
+
+    public override IOperation Apply() {
+      IEnumerable<IScope> scopes = new[] { ExecutionContext.Scope };
+      var zipped = Quality.Select((x, index) => new { Index = index, x.Value });
+      var best = Maximization.Value ? zipped.OrderBy(x => x.Value).First() : zipped.OrderByDescending(x => x.Value).First();
+      for (int j = 0; j < QualityParameter.Depth; j++)
+        scopes = scopes.SelectMany(x => x.SubScopes);
+      IScope currentBestScope = scopes.ToList()[best.Index];
+      var bestSolution = (RealVector)currentBestScope.Variables["RealVector"].Value;
+
+      var bestSolutionMatrix = new DoubleMatrix(bestSolution.Length, 3);
+      var targetNames = bestSolution.ElementNames.ToList();
+      bestSolutionMatrix.RowNames = targetNames;
+      bestSolutionMatrix.ColumnNames = new[] { "Estimated value", "Target value", "Deviation" };
+
+      var problemData = ProblemDataParameter.ActualValue;
+      var row = RowParameter.ActualValue.Value;
+
+      for (int i = 0; i < bestSolution.Length; ++i) {
+        var estimatedValue = bestSolution[i];
+        var targetValue = problemData.Dataset.GetDoubleValue(targetNames[i], row);
+        bestSolutionMatrix[i, 0] = estimatedValue;
+        bestSolutionMatrix[i, 1] = targetValue;
+        bestSolutionMatrix[i, 2] = estimatedValue - targetValue;
+      }
+
+      if (!Results.ContainsKey(BestSolutionResultName)) {
+        Results.Add(new Result(BestSolutionResultName, bestSolutionMatrix));
+      } else {
+        var result = Results[BestSolutionResultName];
+        result.Value = bestSolutionMatrix;
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalParameter.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalParameter.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalParameter.cs	(revision 16133)
@@ -0,0 +1,127 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.GoalSeeking {
+  [Item("GoalParameter", "An object describing a tunable parameter used in goal seeking.")]
+  [StorableClass]
+  public class GoalParameter : NamedItem {
+    [Storable]
+    private double goal;
+    public double Goal {
+      get { return goal; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (goal.IsAlmost(value)) return;
+        goal = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private double weight;
+    public double Weight {
+      get { return weight; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (weight.IsAlmost(value)) return;
+        weight = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private double variance;
+
+    public double Variance {
+      get { return variance; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (variance.IsAlmost(value)) return;
+        variance = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private double step;
+    public double Step {
+      get { return step; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (step.IsAlmost(value)) return;
+        step = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private bool active;
+    public bool Active {
+      get { return active; }
+      set {
+        if (active == value) return;
+        active = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    public override string ToString() {
+      return string.Format("{0} [active: {1}; goal: {2}; weight: {3}; variance: {4}; step: {5}", Name, Active, Goal, Weight, Variance, Step);
+    }
+
+    protected GoalParameter(GoalParameter original, Cloner cloner) : base(original, cloner) {
+      name = original.name;
+      goal = original.goal;
+      weight = original.weight;
+      variance = original.variance;
+      step = original.step;
+      active = original.active;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GoalParameter(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected GoalParameter(bool deserializing) : base(deserializing) { }
+
+    public GoalParameter(string name, double goal, double weight, double variance, double step, bool active = true) {
+      this.name = name;
+      this.goal = goal;
+      this.weight = weight;
+      this.variance = variance;
+      this.step = step;
+      this.active = active;
+    }
+
+    public event EventHandler Changed;
+    private void OnChanged(object sender, EventArgs args) {
+      var changed = Changed;
+      if (changed == null) return;
+      changed(sender, args);
+    }
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingOptimizer.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingOptimizer.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingOptimizer.cs	(revision 16133)
@@ -0,0 +1,573 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.GoalSeeking {
+  internal enum GoalSeekingOptimizerAction { None, Prepare, Start, Stop, Pause }
+
+  [StorableClass]
+  [Item("GoalSeeking Optimizer", "A wrapper for the GoalSeekingProblem class to facilitate adding models and problem data.")]
+  [Creatable("Algorithms")]
+  public class GoalSeekingOptimizer : NamedItem, IOptimizer, IStorableContent {
+    [Storable]
+    private IGoalSeekingProblem problem;
+    public IGoalSeekingProblem Problem {
+      get { return problem; }
+      set {
+        if (value == null || value == problem)
+          return;
+
+        problem = value;
+        // the problem takes precedence over the algorithm. if the algorithm is unsuitable we remove it.
+        if (optimizer != null && !optimizer.ProblemType.IsInstanceOfType(problem)) {
+          optimizer = null;
+          OnAlgorithmChanged();
+        }
+        if (optimizer != null)
+          optimizer.Problem = problem;
+      }
+    }
+
+    [Storable]
+    private IAlgorithm optimizer;
+    public IAlgorithm Optimizer {
+      get { return optimizer; }
+      set {
+        if (value == null || value == optimizer)
+          return;
+
+        // make sure the algorithm is suitable for the problem.
+        if (problem != null && !value.ProblemType.IsInstanceOfType(problem))
+          throw new InvalidOperationException("The algorithm is incompatible with the problem.");
+
+        optimizer = value;
+
+        if (problem != null)
+          optimizer.Problem = problem;
+
+        RegisterOptimizerEvents();
+        OnAlgorithmChanged();
+      }
+    }
+
+    [Storable]
+    private IRegressionProblemData problemData;
+    public IRegressionProblemData ProblemData {
+      get { return problemData; }
+      set {
+        if (value == null || value == problemData)
+          return;
+
+        if (problem == null)
+          throw new InvalidOperationException("Cannot set problem data. Please configure a problem first.");
+
+        problemData = value;
+        problem.Configure(problemData, problemData.TrainingIndices.First());
+        OnProblemDataChanged();
+      }
+    }
+
+    [Storable]
+    private ResultCollection results;
+    public ResultCollection Results {
+      get { return results; }
+      private set {
+        if (value != null)
+          results = value;
+        OnResultsChanged();
+      }
+    }
+
+    private GoalSeekingOptimizerAction gsoAction;
+
+    public GoalSeekingOptimizer() {
+      Name = "Goal Seeking Optimizer";
+    }
+
+    [StorableConstructor]
+    protected GoalSeekingOptimizer(bool deserializing) : base(deserializing) { }
+
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (optimizer != null)
+        RegisterOptimizerEvents();
+    }
+
+    protected GoalSeekingOptimizer(GoalSeekingOptimizer original, Cloner cloner) : base(original, cloner) {
+      this.Optimizer = (IAlgorithm)original.Optimizer.Clone(cloner);
+      this.Problem = (IGoalSeekingProblem)original.Problem.Clone(cloner);
+      this.ProblemData = (IRegressionProblemData)original.ProblemData.Clone(cloner);
+      this.Results = (ResultCollection)original.Results.Clone();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GoalSeekingOptimizer(this, cloner);
+    }
+
+    public EventHandler ProblemChanged;
+    private void OnProblemChanged() {
+      var changed = ProblemChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    public EventHandler AlgorithmChanged;
+    private void OnAlgorithmChanged() {
+      var changed = AlgorithmChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    public EventHandler ProblemDataChanged;
+    private void OnProblemDataChanged() {
+      var changed = ProblemDataChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    public EventHandler ResultsChanged;
+    private void OnResultsChanged() {
+      var changed = ResultsChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    private int calculatedRows;
+    private int currentRow;
+
+    public void Start() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+      if (optimizer == null) return;
+      gsoAction = GoalSeekingOptimizerAction.Start;
+      if (Optimizer.ExecutionState == ExecutionState.Stopped) {
+        Optimizer.Prepare(clearRuns: true);
+        calculatedRows = 0;
+        currentRow = problemData.TrainingIndices.Skip(calculatedRows).First();
+        problem.Configure(problemData, currentRow);
+        optimizer.Prepare();
+      }
+      optimizer.Start();
+    }
+
+    public void Pause() {
+      if (ExecutionState != ExecutionState.Started)
+        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
+      if (optimizer == null) return;
+      gsoAction = GoalSeekingOptimizerAction.Pause;
+      if (optimizer.ExecutionState != ExecutionState.Started) return;
+      // a race-condition may occur when the algorithm has changed the state by itself in the meantime
+      try { optimizer.Pause(); }
+      catch (InvalidOperationException) { }
+    }
+
+    public void Stop() {
+      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
+      if (optimizer == null) return;
+      gsoAction = GoalSeekingOptimizerAction.Stop;
+      if (optimizer.ExecutionState != ExecutionState.Started && optimizer.ExecutionState != ExecutionState.Paused) {
+        OnStopped();
+        return;
+      }
+      // a race-condition may occur when the algorithm has changed the state by itself in the meantime
+      try { optimizer.Stop(); }
+      catch (InvalidOperationException) { }
+    }
+
+    public void Prepare() {
+      Prepare(false);
+    }
+
+    public void Prepare(bool clearRuns) {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
+        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
+
+      if (Results != null)
+        Results.Clear();
+
+      if (optimizer != null) {
+        ExecutionTime = TimeSpan.Zero;
+        if (clearRuns) optimizer.Runs.Clear();
+        gsoAction = GoalSeekingOptimizerAction.Prepare;
+        // a race-condition may occur when the algorithm has changed the state by itself in the meantime
+        try { optimizer.Prepare(clearRuns); }
+        catch (InvalidOperationException) { }
+      } else {
+        ExecutionState = ExecutionState.Stopped;
+      }
+    }
+
+    [Storable]
+    private TimeSpan executionTime;
+    public TimeSpan ExecutionTime {
+      get {
+        if ((Optimizer != null) && (Optimizer.ExecutionState != ExecutionState.Stopped))
+          return executionTime + Optimizer.ExecutionTime;
+        else
+          return executionTime;
+      }
+      private set {
+        executionTime = value;
+        OnExecutionTimeChanged();
+      }
+    }
+
+    public RunCollection Runs {
+      get {
+        if (optimizer == null)
+          return new RunCollection(); // return an empty run collection
+        return Optimizer.Runs;
+      }
+    }
+
+    public IEnumerable<IOptimizer> NestedOptimizers { get; private set; }
+
+    public string Filename { get; set; }
+
+    public new static Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
+    }
+    public override Image ItemImage {
+      get {
+        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPrepared;
+        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStarted;
+        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPaused;
+        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStopped;
+        else return base.ItemImage;
+      }
+    }
+
+    #region Events
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+    }
+
+    #region event firing
+    public ExecutionState ExecutionState { get; private set; }
+    public event EventHandler ExecutionStateChanged;
+    private void OnExecutionStateChanged() {
+      EventHandler handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ExecutionTimeChanged;
+    private void OnExecutionTimeChanged() {
+      EventHandler handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Prepared;
+    private void OnPrepared() {
+      gsoAction = GoalSeekingOptimizerAction.None;
+      ExecutionState = ExecutionState.Prepared;
+      EventHandler handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Started;
+    private void OnStarted() {
+      ExecutionState = ExecutionState.Started;
+      EventHandler handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Paused;
+    private void OnPaused() {
+      gsoAction = GoalSeekingOptimizerAction.None;
+      ExecutionState = ExecutionState.Paused;
+      EventHandler handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Stopped;
+    private void OnStopped() {
+      gsoAction = GoalSeekingOptimizerAction.None;
+      ExecutionState = ExecutionState.Stopped;
+      EventHandler handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    private void OnExceptionOccurred(Exception exception) {
+      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(exception));
+    }
+
+    public event EventHandler OptimizerChanged;
+    private void OnOptimizerChanged() {
+      EventHandler handler = OptimizerChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler RepetitionsChanged;
+    private void OnRepetitionsChanged() {
+      EventHandler handler = RepetitionsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler RepetetionsCounterChanged;
+    private void OnRepetitionsCounterChanged() {
+      EventHandler handler = RepetetionsCounterChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    #region optimizer event handlers
+    private void RegisterOptimizerEvents() {
+      optimizer.ExceptionOccurred += Optimizer_ExceptionOccurred;
+      optimizer.ExecutionTimeChanged += Optimizer_ExecutionTimeChanged;
+      optimizer.Paused += Optimizer_Paused;
+      optimizer.Prepared += Optimizer_Prepared;
+      optimizer.Started += Optimizer_Started;
+      optimizer.Stopped += Optimizer_Stopped;
+    }
+
+    private void DeregisterOptimizerEvents() {
+      optimizer.ExceptionOccurred -= Optimizer_ExceptionOccurred;
+      optimizer.ExecutionTimeChanged -= Optimizer_ExecutionTimeChanged;
+      optimizer.Paused -= Optimizer_Paused;
+      optimizer.Prepared -= Optimizer_Prepared;
+      optimizer.Started -= Optimizer_Started;
+      optimizer.Stopped -= Optimizer_Stopped;
+    }
+
+    private void Optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      OnExceptionOccurred(e.Value);
+    }
+
+    private void Optimizer_ExecutionTimeChanged(object sender, EventArgs e) {
+      OnExecutionTimeChanged();
+    }
+
+    private void Optimizer_Paused(object sender, EventArgs e) {
+      if (ExecutionState == ExecutionState.Started) {
+        OnPaused();
+      }
+    }
+
+    private void Optimizer_Prepared(object sender, EventArgs e) {
+      if (gsoAction == GoalSeekingOptimizerAction.Prepare || ExecutionState == ExecutionState.Stopped) {
+        calculatedRows = 0;
+        ExecutionTime = TimeSpan.Zero;
+        OnPrepared();
+      }
+    }
+
+    private void Optimizer_Started(object sender, EventArgs e) {
+      if (ExecutionState != ExecutionState.Started) {
+        OnStarted();
+      }
+    }
+
+    private void Optimizer_Stopped(object sender, EventArgs e) {
+      calculatedRows++;
+      ExecutionTime += optimizer.ExecutionTime;
+      var remainingRows = problemData.TrainingIndices.Skip(calculatedRows);
+
+      // extract results from the optimizer 
+      GetResults();
+
+      if (gsoAction == GoalSeekingOptimizerAction.Stop)
+        OnStopped();
+      else if (!remainingRows.Any()) {
+        OnStopped();
+      } else switch (gsoAction) {
+          case GoalSeekingOptimizerAction.Pause:
+            OnPaused();
+            break;
+          case GoalSeekingOptimizerAction.Start:
+            currentRow = remainingRows.First();
+            problem.Configure(problemData, currentRow);
+            optimizer.Prepare();
+            optimizer.Start();
+            break;
+          default:
+            if (ExecutionState == ExecutionState.Started) {
+              OnPaused();
+            } else OnStopped();
+            break;
+        }
+    }
+    #endregion
+    #endregion
+
+    #region aggregate results
+    private void GetResults() {
+      if (Problem is MultiObjectiveGoalSeekingProblem) {
+        var m = (DoubleMatrix)optimizer.Results["Pareto Front Solutions"].Value;
+        AggregateMultiObjectiveResults(m);
+      } else if (Problem is SingleObjectiveGoalSeekingProblem) {
+        var m = (DoubleMatrix)optimizer.Results["Best Solution"].Value;
+        AggregateSingleObjectiveResults(m);
+      }
+    }
+
+    private void AggregateSingleObjectiveResults(DoubleMatrix solutions) {
+      var indices = solutions.ColumnNames.Select((x, i) => Tuple.Create(x, i)).ToDictionary(x => x.Item1, x => x.Item2);
+
+      var goals = Problem.Goals.Where(x => x.Active).ToList();
+      var inputs = Problem.Inputs.Where(x => x.Active).ToList();
+
+      if (Results == null)
+        Results = new ResultCollection();
+      // goals
+      if (!Results.ContainsKey("Goals"))
+        Results.Add(new Result("Goals", new ResultCollection()));
+      var goalResults = (ResultCollection)Results["Goals"].Value;
+      foreach (var goal in goals) {
+        var estimatedGoalName = goal.Name + " (estimated)";
+        if (!goalResults.ContainsKey(goal.Name)) {
+          goalResults.Add(new Result(goal.Name, new ScatterPlot(goal.Name, "")));
+        }
+
+        var plot = (ScatterPlot)goalResults[goal.Name].Value;
+        if (!plot.Rows.ContainsKey(goal.Name)) {
+          plot.Rows.Add(new ScatterPlotDataRow { Name = goal.Name });
+          plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedGoalName });
+        }
+
+        plot.Rows[goal.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[goal.Name]]));
+        plot.Rows[estimatedGoalName].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[estimatedGoalName]]));
+      }
+
+      // inputs
+      if (!Results.ContainsKey("Inputs"))
+        Results.Add(new Result("Inputs", new ResultCollection()));
+      var inputResults = (ResultCollection)Results["Inputs"].Value;
+      foreach (var input in inputs) {
+        var estimatedInputName = input.Name + " (estimated)";
+        if (!inputResults.ContainsKey(input.Name)) {
+          inputResults.Add(new Result(input.Name, new ScatterPlot(input.Name, "")));
+        }
+
+        var plot = (ScatterPlot)inputResults[input.Name].Value;
+        if (!plot.Rows.ContainsKey(input.Name)) {
+          plot.Rows.Add(new ScatterPlotDataRow { Name = input.Name });
+          plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedInputName });
+        }
+
+        plot.Rows[input.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[input.Name]]));
+        plot.Rows[estimatedInputName].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[estimatedInputName]]));
+      }
+      // aggregate results as a matrix
+      UpdateResultsMatrix(solutions);
+    }
+
+    private void AggregateMultiObjectiveResults(DoubleMatrix solutions) {
+      int maxSolutionsCount = Math.Min(solutions.Rows, 10);
+
+      var indices = solutions.ColumnNames.Select((x, i) => Tuple.Create(x, i)).ToDictionary(x => x.Item1, x => x.Item2);
+
+      var goals = Problem.Goals.Where(x => x.Active).ToList();
+      var inputs = Problem.Inputs.Where(x => x.Active).ToList();
+
+      if (Results == null)
+        Results = new ResultCollection();
+      // goals
+      if (!Results.ContainsKey("Goals"))
+        Results.Add(new Result("Goals", new ResultCollection()));
+      var goalResults = (ResultCollection)Results["Goals"].Value;
+      foreach (var goal in goals) {
+        var estimatedGoalName = goal.Name + " (estimated)";
+        if (!goalResults.ContainsKey(goal.Name)) {
+          goalResults.Add(new Result(goal.Name, new ScatterPlot(goal.Name, "")));
+        }
+
+        var plot = (ScatterPlot)goalResults[goal.Name].Value;
+        if (!plot.Rows.ContainsKey(goal.Name)) {
+          plot.Rows.Add(new ScatterPlotDataRow { Name = goal.Name, VisualProperties = { PointSize = 5 } });
+        }
+
+        plot.Rows[goal.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[goal.Name]]));
+        for (int i = 0; i < maxSolutionsCount; ++i) {
+          if (!plot.Rows.ContainsKey(estimatedGoalName + i))
+            plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedGoalName + i, VisualProperties = { PointSize = 5 } });
+          plot.Rows[estimatedGoalName + i].Points.Add(new Point2D<double>(currentRow, solutions[i, indices[estimatedGoalName]]));
+        }
+      }
+      // inputs
+      if (!Results.ContainsKey("Inputs"))
+        Results.Add(new Result("Inputs", new ResultCollection()));
+      var inputResults = (ResultCollection)Results["Inputs"].Value;
+      foreach (var input in inputs) {
+        var estimatedInputName = input.Name + " (estimated)";
+        if (!inputResults.ContainsKey(input.Name)) {
+          inputResults.Add(new Result(input.Name, new ScatterPlot(input.Name, "")));
+        }
+
+        var plot = (ScatterPlot)inputResults[input.Name].Value;
+        if (!plot.Rows.ContainsKey(input.Name)) {
+          plot.Rows.Add(new ScatterPlotDataRow { Name = input.Name, VisualProperties = { PointSize = 5 } });
+        }
+
+        plot.Rows[input.Name].Points.Add(new Point2D<double>(currentRow, solutions[0, indices[input.Name]])); // it stays the same for all the rows
+        for (int i = 0; i < maxSolutionsCount; ++i) {
+          if (!plot.Rows.ContainsKey(estimatedInputName + i))
+            plot.Rows.Add(new ScatterPlotDataRow { Name = estimatedInputName + i, VisualProperties = { PointSize = 5 } });
+          plot.Rows[estimatedInputName + i].Points.Add(new Point2D<double>(currentRow, solutions[i, indices[estimatedInputName]]));
+        }
+      }
+      // also add a matrix containing the whole solution data including the row
+      UpdateResultsMatrix(solutions);
+    }
+
+    private void UpdateResultsMatrix(DoubleMatrix solutions) {
+      // also add a matrix containing the whole solution data including the row
+      var rows = problemData.TrainingIndices.Take(calculatedRows).ToList();
+      var m = new DoubleMatrix(calculatedRows, solutions.Columns + 1) {
+        RowNames = rows.Select(x => x.ToString()),
+        ColumnNames = new[] { "Row" }.Concat(solutions.ColumnNames)
+      };
+      DoubleMatrix old = null;
+      if (Results.ContainsKey("Solutions"))
+        old = (DoubleMatrix)Results["Solutions"].Value;
+      else
+        Results.Add(new Result("Solutions", m));
+
+      if (old != null && calculatedRows > 0) {
+        for (int i = 0; i < old.Rows; ++i) {
+          for (int j = 0; j < old.Columns; ++j) {
+            m[i, j] = old[i, j];
+          }
+        }
+      }
+      m[rows.Count - 1, 0] = currentRow;
+      for (int i = 1; i < m.Columns; ++i) {
+        m[rows.Count - 1, i] = solutions[0, i - 1];
+      }
+      Results["Solutions"].Value = m;
+    }
+    #endregion
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingProblem.csproj
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingProblem.csproj	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingProblem.csproj	(revision 16133)
@@ -0,0 +1,231 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{79271BC8-4446-40E2-BB89-9BE4E17174FE}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GoalSeekingProblem</RootNamespace>
+    <AssemblyName>HeuristicLab.GoalSeekingProblem-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <LangVersion>4</LangVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <CodeAnalysisLogFile>HeuristicLab trunk sources\binDebug\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <CodeAnalysisLogFile>HeuristicLab trunk sources\binRelease\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <CodeAnalysisLogFile>HeuristicLab trunk sources\binDebug\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <CodeAnalysisLogFile>HeuristicLab trunk sources\binRelease\Plugin.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+    <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\..\Projects\HeuristicLab\trunk\sources\HeuristicLab trunk sources\binHeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Encodings.RealVectorEncoding-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\HeuristicLab trunk sources\binHeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Analyzers\BestSolutionAnalyzer.cs" />
+    <Compile Include="GoalParameter.cs" />
+    <Compile Include="GoalSeekingOptimizer.cs" />
+    <Compile Include="GoalSeekingUtil.cs" />
+    <Compile Include="InputParameter.cs" />
+    <Compile Include="IGoalSeekingProblem.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="MultiObjectiveGoalSeekingProblem.cs" />
+    <Compile Include="SingleObjectiveGoalSeekingProblem.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingUtil.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingUtil.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/GoalSeekingUtil.cs	(revision 16133)
@@ -0,0 +1,167 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.GoalSeeking {
+  internal static class GoalSeekingUtil {
+    internal static void UpdateTargets(ICheckedItemList<GoalParameter> goals, IEnumerable<IRegressionModel> models, EventHandler changedEventHandler) {
+      var targets = models.Select(x => x.TargetVariable).Distinct().OrderBy(x => x);
+      var dict = goals.ToDictionary(x => x.Name, x => x);
+      goals.Clear();
+      foreach (var t in targets) {
+        GoalParameter gp;
+        if (dict.ContainsKey(t)) {
+          gp = dict[t];
+        } else {
+          var goal = double.NaN;
+          var weight = 1.0;
+          var variance = double.NaN;
+          var step = 1e-6;
+          gp = new GoalParameter(t, goal, weight, variance, step, active: false); // new goals are not active by default as they need to be configured by the user
+          gp.Changed += changedEventHandler;
+        }
+        goals.Add(gp, gp.Active);
+      }
+    }
+
+    internal static void UpdateInputs(ICheckedItemList<InputParameter> inputs, IEnumerable<IRegressionModel> models, EventHandler changedEventHandler) {
+      var variables = models.SelectMany(x => x.VariablesUsedForPrediction).Distinct();
+      var dict = inputs.ToDictionary(x => x.Name, x => x); // save old parameter settings
+      inputs.Clear();
+      foreach (var v in variables) {
+        InputParameter ip;
+        if (dict.ContainsKey(v)) {
+          ip = dict[v];
+        } else {
+          ip = new InputParameter(v, double.NaN, -1, 1, 1e-6, active: false); // new inputs are not active by default. the user needs to configure them first
+          ip.Changed += changedEventHandler;
+        }
+        inputs.Add(ip, ip.Active);
+      }
+    }
+
+    internal static RealVectorEncoding CreateEncoding(IEnumerable<InputParameter> inputParameters) {
+      var encoding = new RealVectorEncoding(inputParameters.Count());
+      encoding.Bounds = new DoubleMatrix(encoding.Length, 2); // only two columns: min and max
+      encoding.Bounds.RowNames = inputParameters.Select(x => x.Name);
+      encoding.Bounds.ColumnNames = new[] { "Min.", "Max." };
+
+      int i = 0;
+      foreach (var parameter in inputParameters) {
+        encoding.Bounds[i, 0] = parameter.Min;
+        encoding.Bounds[i, 1] = parameter.Max;
+        ++i;
+      }
+      return encoding;
+    }
+
+    internal static void UpdateEncoding(RealVectorEncoding encoding, IEnumerable<InputParameter> inputParameters) {
+      encoding.Length = inputParameters.Count();
+      encoding.Bounds = new DoubleMatrix(encoding.Length, 2);
+      encoding.Bounds.RowNames = inputParameters.Select(x => x.Name);
+      encoding.Bounds.ColumnNames = new[] { "Min.", "Max." };
+
+      int i = 0;
+      foreach (var parameter in inputParameters) {
+        encoding.Bounds[i, 0] = parameter.Min;
+        encoding.Bounds[i, 1] = parameter.Max;
+        ++i;
+      }
+    }
+
+    internal static void ValidateGoalsAndInputs(IEnumerable<GoalParameter> goals, IEnumerable<InputParameter> inputs) {
+      var notConfiguredGoals = goals.Where(x => x.Active && (double.IsNaN(x.Variance) || double.IsNaN(x.Goal))).ToList();
+      var notConfiguredInputs = inputs.Where(x => x.Active && (double.IsNaN(x.Min) || double.IsNaN(x.Max) || double.IsNaN(x.Value))).ToList();
+      StringBuilder sb = null;
+      if (notConfiguredGoals.Any()) {
+        sb = new StringBuilder();
+        sb.AppendLine("The following GoalParameters are not configured.");
+        foreach (var goal in notConfiguredGoals) {
+          sb.AppendLine(goal.Name);
+        }
+      }
+      if (notConfiguredInputs.Any()) {
+        if (sb == null)
+          sb = new StringBuilder();
+        sb.AppendLine("The following InpuTParameters are not configured.");
+        foreach (var input in notConfiguredInputs) {
+          sb.AppendLine(input.Name);
+        }
+      }
+      if (sb != null)
+        throw new InvalidOperationException(sb.ToString());
+    }
+
+    internal static void Configure(IEnumerable<GoalParameter> goals, IEnumerable<InputParameter> inputs, IRegressionProblemData problemData, int row) {
+      var inputMap = inputs.ToDictionary(x => x.Name, x => x);
+      var goalMap = goals.ToDictionary(x => x.Name, x => x);
+
+      foreach (var variable in problemData.Dataset.DoubleVariables) {
+        if (inputMap.ContainsKey(variable)) {
+          var values = problemData.Dataset.GetReadOnlyDoubleValues(variable);
+          var input = inputMap[variable];
+          input.Value = values[row];
+          double min = values[0], max = values[0];
+          foreach (var v in values) {
+            if (min > v) min = v;
+            if (max < v) max = v;
+          }
+          input.Min = min;
+          input.Max = max;
+        } else if (goalMap.ContainsKey(variable)) {
+          var values = problemData.Dataset.GetReadOnlyDoubleValues(variable);
+          var goal = goalMap[variable];
+          goal.Variance = values.Variance();
+          goal.Goal = values[row];
+        }
+      }
+    }
+
+    internal static void Goals_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<GoalParameter>> args) {
+      var goals = (CheckedItemList<GoalParameter>)sender;
+      foreach (var item in args.Items.Select(x => x.Value)) {
+        item.Active = goals.ItemChecked(item);
+      }
+    }
+
+    internal static void Inputs_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<InputParameter>> args) {
+      var inputs = (CheckedItemList<InputParameter>)sender;
+      foreach (var item in args.Items.Select(x => x.Value)) {
+        item.Active = inputs.ItemChecked(item);
+      }
+    }
+
+    internal static void RaiseEvent(object sender, EventHandler handler) {
+      if (handler == null) return;
+      handler(sender, EventArgs.Empty);
+    }
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/IGoalSeekingProblem.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/IGoalSeekingProblem.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/IGoalSeekingProblem.cs	(revision 16133)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.GoalSeeking {
+  public interface IGoalSeekingProblem : IProblem {
+    void Configure(IRegressionProblemData problemData, int row);
+    //rounding ? 
+    IEnumerable<double> GetEstimatedGoalValues(IEnumerable<double> parameterValues, bool round = false);
+
+    //Models?
+    IEnumerable<IRegressionModel> Models { get; }
+    void AddModel(IRegressionModel model);
+    void RemoveModel(IRegressionModel model);
+
+    //targets and parameters
+    IEnumerable<GoalParameter> Goals { get; }
+    IEnumerable<InputParameter> Inputs { get; }
+
+    //events
+    event EventHandler ModelsChanged;
+    event EventHandler TargetsChanged;
+    event EventHandler ParametersChanged;
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/InputParameter.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/InputParameter.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/InputParameter.cs	(revision 16133)
@@ -0,0 +1,126 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.GoalSeeking {
+  [Item("InputParameter", "An object describing a target for the goal seeking.")]
+  [StorableClass]
+  public class InputParameter : NamedItem {
+    [Storable]
+    private double min;
+    public double Min {
+      get { return min; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (min.IsAlmost(value)) return;
+        min = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private double max;
+    public double Max {
+      get { return max; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (max.IsAlmost(value)) return;
+        max = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private double step;
+    public double Step {
+      get { return step; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (step.IsAlmost(value)) return;
+        step = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private double value;
+    public double Value {
+      get { return value; }
+      set {
+        if (double.IsNaN(value) || double.IsInfinity(value)) return;
+        if (this.value.IsAlmost(value)) return;
+        this.value = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private bool active;
+    public bool Active {
+      get { return active; }
+      set {
+        if (active == value) return;
+        active = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    public override string ToString() {
+      return string.Format("{0} [active: {1}; value: {2}; min: {3}; max: {4}; step: {5}]", Name, Active, Value, Min, Max, Step);
+    }
+
+    protected InputParameter(InputParameter original, Cloner cloner) : base(original, cloner) {
+      name = original.name;
+      min = original.min;
+      max = original.max;
+      step = original.step;
+      value = original.value;
+      active = original.active;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InputParameter(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected InputParameter(bool deserializing) : base(deserializing) { }
+
+    public InputParameter(string name, double value, double min, double max, double step, bool active = true) {
+      this.name = name;
+      this.value = value;
+      this.min = min;
+      this.max = max;
+      this.step = step;
+      this.active = active;
+    }
+
+    public event EventHandler Changed;
+    private void OnChanged(object sender, EventArgs args) {
+      var changed = Changed;
+      if (changed == null) return;
+      changed(sender, args);
+    }
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/MultiObjectiveGoalSeekingProblem.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/MultiObjectiveGoalSeekingProblem.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/MultiObjectiveGoalSeekingProblem.cs	(revision 16133)
@@ -0,0 +1,304 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.GoalSeeking {
+  [Item("Goal seeking problem (multi-objective)", "Represents a single objective optimization problem which uses configurable regression models to evaluate targets from a given dataset.")]
+  [Creatable("Problems")]
+  [StorableClass]
+  public sealed class MultiObjectiveGoalSeekingProblem : MultiObjectiveBasicProblem<RealVectorEncoding>, IGoalSeekingProblem {
+    #region parameter names
+    private const string InputsParameterName = "Inputs";
+    private const string GoalsParameterName = "Goals";
+    private const string ModelsParameterName = "Models";
+    private const string QualitySumCutoffParameterName = "QualitySumCutoff";
+    #endregion
+
+    #region parameters
+    public IValueParameter<CheckedItemList<InputParameter>> InputsParameter {
+      get { return (IValueParameter<CheckedItemList<InputParameter>>)Parameters[InputsParameterName]; }
+    }
+    public IValueParameter<CheckedItemList<GoalParameter>> GoalsParameter {
+      get { return (IValueParameter<CheckedItemList<GoalParameter>>)Parameters[GoalsParameterName]; }
+    }
+    public IFixedValueParameter<ItemList<IRegressionModel>> ModelsParameter {
+      get { return (IFixedValueParameter<ItemList<IRegressionModel>>)Parameters[ModelsParameterName]; }
+    }
+    public IFixedValueParameter<DoubleValue> QualitySumCutoffParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters[QualitySumCutoffParameterName]; }
+    }
+    #endregion
+
+    #region IGoalSeekingProblem implementation
+    public IEnumerable<IRegressionModel> Models {
+      get { return ModelsParameter.Value; }
+    }
+
+    public IEnumerable<GoalParameter> Goals {
+      get { return GoalsParameter.Value; }
+    }
+
+    public IEnumerable<InputParameter> Inputs {
+      get { return InputsParameter.Value; }
+    }
+
+    public void AddModel(IRegressionModel model) {
+      var models = ModelsParameter.Value;
+      models.Add(model);
+      GoalSeekingUtil.RaiseEvent(this, ModelsChanged);
+    }
+
+    public void RemoveModel(IRegressionModel model) {
+      var models = ModelsParameter.Value;
+      models.Remove(model);
+      GoalSeekingUtil.RaiseEvent(this, ModelsChanged);
+    }
+
+    public void Configure(IRegressionProblemData problemData, int row) {
+      GoalSeekingUtil.Configure(Goals, Inputs, problemData, row);
+    }
+
+    public IEnumerable<double> GetEstimatedGoalValues(IEnumerable<double> parameterValues, bool round = false) {
+      var ds = (ModifiableDataset)dataset.Clone();
+      foreach (var parameter in ActiveInputs.Zip(parameterValues, (p, v) => new { Name = p.Name, Value = v })) {
+        ds.SetVariableValue(parameter.Value, parameter.Name, 0);
+      }
+      var rows = new[] { 0 }; // actually just one row
+      var estimatedValues =
+        round ? ActiveGoals.Select(t => RoundToNearestStepMultiple(GetModels(t.Name).Average(m => m.GetEstimatedValues(ds, rows).Single()), t.Step))
+              : ActiveGoals.Select(t => GetModels(t.Name).Average(m => m.GetEstimatedValues(ds, rows).Single()));
+      return estimatedValues;
+    }
+
+    public event EventHandler ModelsChanged;
+    public event EventHandler TargetsChanged;
+    public event EventHandler ParametersChanged;
+    #endregion
+
+    private IEnumerable<GoalParameter> ActiveGoals {
+      get { return Goals.Where(x => x.Active); }
+    }
+    private IEnumerable<InputParameter> ActiveInputs {
+      get { return Inputs.Where(x => x.Active); }
+    }
+    private double QualitySumCutoff {
+      get { return QualitySumCutoffParameter.Value.Value; }
+    }
+
+    [Storable]
+    private ModifiableDataset dataset; // modifiable dataset
+
+    [Storable]
+    private bool[] maximization;
+    public override bool[] Maximization {
+      get { return maximization ?? new bool[] { false }; }
+    }
+
+    public ValueParameter<BoolArray> MaximizationParameter {
+      get { return (ValueParameter<BoolArray>)Parameters["Maximization"]; }
+    }
+
+    #region constructors
+    [StorableConstructor]
+    private MultiObjectiveGoalSeekingProblem(bool deserializing) : base(deserializing) { }
+
+    private MultiObjectiveGoalSeekingProblem(MultiObjectiveGoalSeekingProblem original, Cloner cloner) : base(original, cloner) {
+      this.dataset = cloner.Clone(original.dataset);
+
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiObjectiveGoalSeekingProblem(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    public MultiObjectiveGoalSeekingProblem() {
+      dataset = new ModifiableDataset();
+      Parameters.Add(new ValueParameter<CheckedItemList<InputParameter>>(InputsParameterName));
+      Parameters.Add(new ValueParameter<CheckedItemList<GoalParameter>>(GoalsParameterName));
+      Parameters.Add(new FixedValueParameter<ItemList<IRegressionModel>>(ModelsParameterName, new ItemList<IRegressionModel>()));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(QualitySumCutoffParameterName, new DoubleValue(0.2)));
+      QualitySumCutoffParameter.Hidden = true;
+      EncodingParameter.Hidden = true;
+      EvaluatorParameter.Hidden = true;
+      SolutionCreatorParameter.Hidden = true;
+      MaximizationParameter.Hidden = true;
+      RegisterEvents();
+    }
+    #endregion
+
+    public override double[] Evaluate(Individual individual, IRandom random) {
+      var vector = individual.RealVector();
+      vector.ElementNames = ActiveInputs.Select(x => x.Name);
+      int i = 0;
+      // round vector according to parameter step sizes
+      foreach (var parameter in ActiveInputs) {
+        vector[i] = RoundToNearestStepMultiple(vector[i], parameter.Step);
+        ++i;
+      }
+      var estimatedValues = GetEstimatedGoalValues(vector, round: true);
+      var qualities = ActiveGoals.Zip(estimatedValues, (t, v) => new { Target = t, EstimatedValue = v })
+                                 .Select(x => x.Target.Weight * Math.Pow(x.EstimatedValue - x.Target.Goal, 2) / x.Target.Variance);
+      return qualities.ToArray();
+    }
+
+    #region pareto analyzer
+    public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) {
+      var matrix = FilterFrontsByQualitySum(individuals, qualities, Math.Max(QualitySumCutoff, qualities.Min(x => x.Sum())));
+      const string resultName = "Pareto Front Solutions"; // disclaimer: not really a pareto front
+      if (!results.ContainsKey(resultName)) {
+        results.Add(new Result(resultName, matrix));
+      } else {
+        results[resultName].Value = matrix;
+      }
+      base.Analyze(individuals, qualities, results, random);
+    }
+
+    private DoubleMatrix FilterFrontsByQualitySum(Individual[] individuals, double[][] qualities, double qualitySumCutoff) {
+      var activeParameters = ActiveInputs.ToList();
+      var activeGoals = ActiveGoals.ToList();
+      var filteredModels = new List<double[]>();
+      var rowNames = new List<string>();
+      // build list of column names by combining target and parameter names (with their respective original and estimated values)
+      var columnNames = new List<string> { "Quality Sum" };
+      foreach (var target in activeGoals) {
+        columnNames.Add(target.Name);
+        columnNames.Add(target.Name + " (estimated)");
+      }
+      foreach (var parameter in activeParameters) {
+        columnNames.Add(parameter.Name);
+        columnNames.Add(parameter.Name + " (estimated)");
+        columnNames.Add(parameter.Name + " (deviation)");
+      }
+      // filter models based on their quality sum; remove duplicate models
+      var dec = new DoubleEqualityComparer(); // comparer which uses the IsAlmost method for comparing floating point numbers
+      for (int i = 0; i < individuals.Length; ++i) {
+        var qualitySum = qualities[i].Sum();
+        if (qualitySum > qualitySumCutoff)
+          continue;
+        var vector = individuals[i].RealVector();
+        var estimatedValues = GetEstimatedGoalValues(vector).ToList();
+        var rowValues = new double[columnNames.Count];
+        rowValues[0] = qualitySum;
+        int offset = 1;
+        for (int j = 0; j < activeGoals.Count * 2; j += 2) {
+          int k = j + offset;
+          var goal = activeGoals[j / 2].Goal;
+          rowValues[k] = goal; // original value 
+          rowValues[k + 1] = estimatedValues[j / 2]; // estimated value
+        }
+        offset += activeGoals.Count * 2;
+        for (int j = 0; j < activeParameters.Count * 3; j += 3) {
+          int k = j + offset;
+          rowValues[k] = activeParameters[j / 3].Value;
+          rowValues[k + 1] = vector[j / 3];
+          rowValues[k + 2] = rowValues[k + 1] - rowValues[k];
+        }
+        if (!filteredModels.Any(x => x.SequenceEqual(rowValues, dec))) {
+          rowNames.Add((i + 1).ToString());
+          filteredModels.Add(rowValues);
+        }
+      }
+      var matrix = new DoubleMatrix(filteredModels.Count, columnNames.Count) { RowNames = rowNames, ColumnNames = columnNames, SortableView = true };
+      for (int i = 0; i < filteredModels.Count; ++i) {
+        for (int j = 0; j < filteredModels[i].Length; ++j) {
+          matrix[i, j] = filteredModels[i][j];
+        }
+      }
+      return matrix;
+    }
+    #endregion
+
+    #region event handlers
+    private void RegisterEvents() {
+      ModelsParameter.Value.ItemsAdded += ModelCollection_ItemsChanged;
+      ModelsParameter.Value.ItemsRemoved += ModelCollection_ItemsChanged;
+      GoalsParameter.Value.CheckedItemsChanged += GoalSeekingUtil.Goals_CheckedItemsChanged;
+      InputsParameter.Value.CheckedItemsChanged += GoalSeekingUtil.Inputs_CheckedItemsChanged;
+
+      foreach (var input in Inputs)
+        input.Changed += InputParameterChanged;
+
+      foreach (var goal in Goals)
+        goal.Changed += GoalParameterChanged;
+    }
+
+    private void ModelCollection_ItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<IRegressionModel>> e) {
+      if (e.Items == null || !e.Items.Any()) return;
+      GoalSeekingUtil.UpdateInputs(InputsParameter.Value, Models, InputParameterChanged);
+      GoalSeekingUtil.UpdateEncoding(Encoding, ActiveInputs);
+      dataset = Inputs.Any() ? new ModifiableDataset(Inputs.Select(x => x.Name), Inputs.Select(x => new List<double> { x.Value })) : new ModifiableDataset();
+      GoalSeekingUtil.UpdateTargets(GoalsParameter.Value, Models, GoalParameterChanged);
+      GoalSeekingUtil.RaiseEvent(this, ModelsChanged);
+    }
+
+    private void InputParameterChanged(object sender, EventArgs args) {
+      var inputParameter = (InputParameter)sender;
+      var inputs = InputsParameter.Value;
+      if (inputs.ItemChecked(inputParameter) != inputParameter.Active)
+        inputs.SetItemCheckedState(inputParameter, inputParameter.Active);
+      GoalSeekingUtil.UpdateEncoding(Encoding, ActiveInputs);
+    }
+
+    private void GoalParameterChanged(object sender, EventArgs args) {
+      var goalParameter = (GoalParameter)sender;
+      var goals = GoalsParameter.Value;
+      if (goals.ItemChecked(goalParameter) != goalParameter.Active)
+        goals.SetItemCheckedState(goalParameter, goalParameter.Active);
+    }
+    #endregion
+
+    #region helper methods
+    // method which throws an exception that can be caught in the event handler if the check fails
+    private void CheckIfDatasetContainsTarget(string target) {
+      if (dataset.DoubleVariables.All(x => x != target))
+        throw new ArgumentException(string.Format("Model target \"{0}\" does not exist in the dataset.", target));
+    }
+    private static double RoundToNearestStepMultiple(double value, double step) {
+      return step * (long)Math.Round(value / step);
+    }
+    private IEnumerable<IRegressionModel> GetModels(string target) {
+      return Models.Where(x => x.TargetVariable == target);
+    }
+    private class DoubleEqualityComparer : IEqualityComparer<double> {
+      public bool Equals(double x, double y) { return x.IsAlmost(y); }
+      public int GetHashCode(double obj) { return obj.GetHashCode(); }
+    }
+    #endregion
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Plugin.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Plugin.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Plugin.cs	(revision 16133)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GoalSeekingProblem {
+  [Plugin("HeuristicLab.GoalSeekingProblem", "3.4.0.0")]
+  [PluginFile("HeuristicLab.GoalSeekingProblem-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
+  public class HeuristicLabProcessParameterOptimizationPlugin : PluginBase {
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Plugin.cs.frame
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Plugin.cs.frame	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Plugin.cs.frame	(revision 16133)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GoalSeekingProblem {
+  [Plugin("HeuristicLab.GoalSeekingProblem", "3.4.0.0")]
+  [PluginFile("HeuristicLab.GoalSeekingProblem-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
+  public class HeuristicLabProcessParameterOptimizationPlugin : PluginBase {
+  }
+}
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/PreBuildEvent.cmd
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/PreBuildEvent.cmd	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/PreBuildEvent.cmd	(revision 16133)
@@ -0,0 +1,11 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+GOTO Done
+
+:Error_Handling
+ECHO There was an error while running subwcrev. Please verify that the *.cs.frame files have been correctly converted to *.cs files, otherwise HeuristicLab won't build. 
+exit 0
+
+:Done
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Properties/AssemblyInfo.cs.frame	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/Properties/AssemblyInfo.cs.frame	(revision 16133)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-$year$ Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.ProcessParameterOptimization")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7c14407e-6980-465b-ba3a-4a916d48989b")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.11.$WCREV$")]
Index: /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/SingleObjectiveGoalSeekingProblem.cs
===================================================================
--- /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/SingleObjectiveGoalSeekingProblem.cs	(revision 16133)
+++ /branches/2679_HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/SingleObjectiveGoalSeekingProblem.cs	(revision 16133)
@@ -0,0 +1,266 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.GoalSeeking {
+  [Item("Goal seeking problem (single-objective)", "Represents a single objective optimization problem which uses configurable regression solutions to evaluate targets from a given dataset.")]
+  [Creatable("Problems")]
+  [StorableClass]
+  public sealed class SingleObjectiveGoalSeekingProblem : SingleObjectiveBasicProblem<RealVectorEncoding>, IGoalSeekingProblem {
+    #region parameter names
+    private const string InputsParameterName = "Inputs";
+    private const string GoalsParameterName = "Goals";
+    private const string ModelsParameterName = "Models";
+    #endregion
+
+    #region parameters
+    public IValueParameter<CheckedItemList<InputParameter>> InputsParameter {
+      get { return (IValueParameter<CheckedItemList<InputParameter>>)Parameters[InputsParameterName]; }
+    }
+    public IValueParameter<CheckedItemList<GoalParameter>> GoalsParameter {
+      get { return (IValueParameter<CheckedItemList<GoalParameter>>)Parameters[GoalsParameterName]; }
+    }
+    public IFixedValueParameter<ItemList<IRegressionModel>> ModelsParameter {
+      get { return (IFixedValueParameter<ItemList<IRegressionModel>>)Parameters[ModelsParameterName]; }
+    }
+    #endregion
+
+    #region IGoalSeekingProblem implementation
+    public IEnumerable<IRegressionModel> Models {
+      get { return ModelsParameter.Value; }
+    }
+
+    public IEnumerable<GoalParameter> Goals {
+      get { return GoalsParameter.Value; }
+    }
+
+    public IEnumerable<InputParameter> Inputs {
+      get { return InputsParameter.Value; }
+    }
+
+    public void AddModel(IRegressionModel model) {
+      var models = ModelsParameter.Value;
+      models.Add(model);
+      GoalSeekingUtil.RaiseEvent(this, ModelsChanged);
+    }
+
+    public void RemoveModel(IRegressionModel model) {
+      var models = ModelsParameter.Value;
+      models.Remove(model);
+      GoalSeekingUtil.RaiseEvent(this, ModelsChanged);
+    }
+
+    public void Configure(IRegressionProblemData problemData, int row) {
+      GoalSeekingUtil.Configure(Goals, Inputs, problemData, row);
+    }
+
+    public IEnumerable<double> GetEstimatedGoalValues(IEnumerable<double> parameterValues, bool round = false) {
+      var ds = (ModifiableDataset)dataset.Clone();
+      foreach (var parameter in ActiveInputs.Zip(parameterValues, (p, v) => new { Name = p.Name, Value = v })) {
+        ds.SetVariableValue(parameter.Value, parameter.Name, 0);
+      }
+      var rows = new[] { 0 }; // actually just one row
+      var estimatedValues =
+        round ? ActiveGoals.Select(t => RoundToNearestStepMultiple(GetModels(t.Name).Average(m => m.GetEstimatedValues(ds, rows).Single()), t.Step))
+              : ActiveGoals.Select(t => GetModels(t.Name).Average(m => m.GetEstimatedValues(ds, rows).Single()));
+      return estimatedValues;
+    }
+
+    public event EventHandler ModelsChanged;
+    public event EventHandler TargetsChanged;
+    public event EventHandler ParametersChanged;
+    #endregion
+
+    private IEnumerable<GoalParameter> ActiveGoals {
+      get { return Goals.Where(x => x.Active); }
+    }
+    private IEnumerable<InputParameter> ActiveInputs {
+      get { return Inputs.Where(x => x.Active); }
+    }
+
+    [Storable]
+    private ModifiableDataset dataset; // modifiable dataset
+
+    public override bool Maximization {
+      get { return false; }
+    }
+
+    #region constructors
+    [StorableConstructor]
+    private SingleObjectiveGoalSeekingProblem(bool deserializing) : base(deserializing) { }
+
+    private SingleObjectiveGoalSeekingProblem(SingleObjectiveGoalSeekingProblem original, Cloner cloner) : base(original, cloner) {
+      this.dataset = cloner.Clone(original.dataset);
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveGoalSeekingProblem(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    public SingleObjectiveGoalSeekingProblem() {
+      dataset = new ModifiableDataset();
+      Parameters.Add(new ValueParameter<CheckedItemList<InputParameter>>(InputsParameterName));
+      Parameters.Add(new ValueParameter<CheckedItemList<GoalParameter>>(GoalsParameterName));
+      Parameters.Add(new FixedValueParameter<ItemList<IRegressionModel>>(ModelsParameterName, new ItemList<IRegressionModel>()));
+      EncodingParameter.Hidden = true;
+      EvaluatorParameter.Hidden = true;
+      SolutionCreatorParameter.Hidden = true;
+      RegisterEvents();
+    }
+    #endregion
+
+    public override double Evaluate(Individual individual, IRandom random) {
+      var vector = individual.RealVector();
+      vector.ElementNames = ActiveInputs.Select(x => x.Name);
+      int i = 0;
+      // round vector according to parameter step sizes
+      foreach (var parameter in ActiveInputs) {
+        vector[i] = RoundToNearestStepMultiple(vector[i], parameter.Step);
+        ++i;
+      }
+      var estimatedValues = GetEstimatedGoalValues(vector, round: true);
+      var quality = ActiveGoals.Zip(estimatedValues, (t, v) => new { Target = t, EstimatedValue = v })
+                               .Average(x => x.Target.Weight * Math.Pow(x.EstimatedValue - x.Target.Goal, 2) / x.Target.Variance);
+      return quality;
+    }
+
+    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
+      var zipped = individuals.Zip(qualities, (ind, qual) => new { Individual = ind, Quality = qual }).OrderBy(x => x.Quality);
+      var best = Maximization ? zipped.Last() : zipped.First();
+      var realVector = best.Individual.RealVector();
+      const string resultName = "Best Solution";
+
+      var columnNames = new List<string>();
+      foreach (var goal in ActiveGoals) {
+        columnNames.Add(goal.Name);
+        columnNames.Add(goal.Name + " (estimated)");
+      }
+      foreach (var input in ActiveInputs) {
+        columnNames.Add(input.Name);
+        columnNames.Add(input.Name + " (estimated)");
+        columnNames.Add(input.Name + " (deviation)");
+      }
+
+      var m = new DoubleMatrix(1, columnNames.Count) { ColumnNames = columnNames };
+      int i = 0;
+
+      var goals = ActiveGoals.Zip(GetEstimatedGoalValues(realVector, round: true),
+        (goal, value) => new { TargetValue = goal.Goal, EstimatedValue = value });
+
+      foreach (var goal in goals) {
+        m[0, i] = goal.TargetValue;
+        m[0, i + 1] = goal.EstimatedValue;
+        i += 2;
+      }
+
+      var inputs = ActiveInputs.Zip(realVector,
+        (input, value) => new { ActualValue = input.Value, EstimatedValue = value });
+
+      foreach (var input in inputs) {
+        m[0, i] = input.ActualValue;
+        m[0, i + 1] = input.EstimatedValue;
+        m[0, i + 2] = m[0, i] - m[0, i + 1];
+        i += 3;
+      }
+
+      if (!results.ContainsKey(resultName)) {
+        results.Add(new Result(resultName, m));
+      } else {
+        results[resultName].Value = m;
+      }
+
+      base.Analyze(individuals, qualities, results, random);
+    }
+
+    #region event handlers
+    private void RegisterEvents() {
+      ModelsParameter.Value.ItemsAdded += ModelCollection_ItemsChanged;
+      ModelsParameter.Value.ItemsRemoved += ModelCollection_ItemsChanged;
+      GoalsParameter.Value.CheckedItemsChanged += GoalSeekingUtil.Goals_CheckedItemsChanged;
+      InputsParameter.Value.CheckedItemsChanged += GoalSeekingUtil.Inputs_CheckedItemsChanged;
+
+      foreach (var input in Inputs)
+        input.Changed += InputParameterChanged;
+
+      foreach (var goal in Goals)
+        goal.Changed += GoalParameterChanged;
+    }
+
+    private void ModelCollection_ItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<IRegressionModel>> e) {
+      if (e.Items == null || !e.Items.Any()) return;
+      GoalSeekingUtil.UpdateInputs(InputsParameter.Value, Models, InputParameterChanged);
+      GoalSeekingUtil.UpdateEncoding(Encoding, ActiveInputs);
+      dataset = Inputs.Any() ? new ModifiableDataset(Inputs.Select(x => x.Name), Inputs.Select(x => new List<double> { x.Value })) : new ModifiableDataset();
+      GoalSeekingUtil.UpdateTargets(GoalsParameter.Value, Models, GoalParameterChanged);
+      GoalSeekingUtil.RaiseEvent(this, ModelsChanged);
+    }
+
+    private void InputParameterChanged(object sender, EventArgs args) {
+      var inputParameter = (InputParameter)sender;
+      var inputs = InputsParameter.Value;
+      if (inputs.ItemChecked(inputParameter) != inputParameter.Active)
+        inputs.SetItemCheckedState(inputParameter, inputParameter.Active);
+      GoalSeekingUtil.UpdateEncoding(Encoding, ActiveInputs);
+    }
+
+    private void GoalParameterChanged(object sender, EventArgs args) {
+      var goalParameter = (GoalParameter)sender;
+      var goals = GoalsParameter.Value;
+      if (goals.ItemChecked(goalParameter) != goalParameter.Active)
+        goals.SetItemCheckedState(goalParameter, goalParameter.Active);
+    }
+    #endregion
+
+    #region helper methods
+    // method which throws an exception that can be caught in the event handler if the check fails
+    private void CheckIfDatasetContainsTarget(string target) {
+      if (dataset.DoubleVariables.All(x => x != target))
+        throw new ArgumentException(string.Format("Model target \"{0}\" does not exist in the dataset.", target));
+    }
+
+    private IEnumerable<IRegressionModel> GetModels(string target) {
+      return Models.Where(x => x.TargetVariable == target);
+    }
+
+    private static double RoundToNearestStepMultiple(double value, double step) {
+      return step * (long)Math.Round(value / step);
+    }
+    #endregion
+  }
+}
