Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.BioBoost.sln
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.BioBoost.sln	(revision 13071)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.BioBoost.sln	(revision 13072)
@@ -5,4 +5,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.BioBoost-3.3", "HeuristicLab.Problems.BioBoost\3.3\HeuristicLab.Problems.BioBoost-3.3.csproj", "{61D4AF50-8A40-44B9-9CD0-413F65D2235C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.BioBoost.Views-3.3", "HeuristicLab.Problems.BioBoost.Views\3.3\HeuristicLab.Problems.BioBoost.Views-3.3.csproj", "{473AB0CD-0B71-471D-968C-A543B197E134}"
 EndProject
 Global
@@ -28,4 +30,16 @@
 		{61D4AF50-8A40-44B9-9CD0-413F65D2235C}.Release|x86.ActiveCfg = Release|x86
 		{61D4AF50-8A40-44B9-9CD0-413F65D2235C}.Release|x86.Build.0 = Release|x86
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Debug|x64.ActiveCfg = Debug|x64
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Debug|x64.Build.0 = Debug|x64
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Debug|x86.ActiveCfg = Debug|x86
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Debug|x86.Build.0 = Debug|x86
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Release|Any CPU.Build.0 = Release|Any CPU
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Release|x64.ActiveCfg = Release|x64
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Release|x64.Build.0 = Release|x64
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Release|x86.ActiveCfg = Release|x86
+		{473AB0CD-0B71-471D-968C-A543B197E134}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.Designer.cs	(revision 13072)
@@ -0,0 +1,276 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostCompoundSolutionEditor {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.Label vectorLayersLabel;
+      System.Windows.Forms.Label valueLayersLabel;
+      this.mapBox = new SharpMap.Forms.MapBox();
+      this.transportLayersListBox = new System.Windows.Forms.ListBox();
+      this.utilizationLayersListBox = new System.Windows.Forms.ListBox();
+      this.regionNameLabel = new System.Windows.Forms.Label();
+      this.regionDescriptionLabel = new System.Windows.Forms.Label();
+      this.qualityLabel = new System.Windows.Forms.Label();
+      this.feedstockCostsLabel = new System.Windows.Forms.Label();
+      this.transportCostsLabel = new System.Windows.Forms.Label();
+      this.optimizeTransportsButton = new System.Windows.Forms.Button();
+      this.optimizeUtilizationsButton = new System.Windows.Forms.Button();
+      this.statusStrip = new System.Windows.Forms.StatusStrip();
+      this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
+      this.costPerFuelLabel = new System.Windows.Forms.Label();
+      this.transportInfoLabel = new System.Windows.Forms.Label();
+      vectorLayersLabel = new System.Windows.Forms.Label();
+      valueLayersLabel = new System.Windows.Forms.Label();
+      this.statusStrip.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // vectorLayersLabel
+      // 
+      vectorLayersLabel.AutoSize = true;
+      vectorLayersLabel.Location = new System.Drawing.Point(3, 86);
+      vectorLayersLabel.Margin = new System.Windows.Forms.Padding(3);
+      vectorLayersLabel.Name = "vectorLayersLabel";
+      vectorLayersLabel.Size = new System.Drawing.Size(72, 13);
+      vectorLayersLabel.TabIndex = 9;
+      vectorLayersLabel.Text = "Vector Layers";
+      // 
+      // valueLayersLabel
+      // 
+      valueLayersLabel.AutoSize = true;
+      valueLayersLabel.Location = new System.Drawing.Point(3, 216);
+      valueLayersLabel.Name = "valueLayersLabel";
+      valueLayersLabel.Size = new System.Drawing.Size(68, 13);
+      valueLayersLabel.TabIndex = 10;
+      valueLayersLabel.Text = "Value Layers";
+      // 
+      // mapBox
+      // 
+      this.mapBox.ActiveTool = SharpMap.Forms.MapBox.Tools.Pan;
+      this.mapBox.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.mapBox.Cursor = System.Windows.Forms.Cursors.Hand;
+      this.mapBox.FineZoomFactor = 10D;
+      this.mapBox.Location = new System.Drawing.Point(189, 31);
+      this.mapBox.MapQueryMode = SharpMap.Forms.MapBox.MapQueryType.VisibleLayers;
+      this.mapBox.Name = "mapBox";
+      this.mapBox.PanOnClick = false;
+      this.mapBox.PreviewMode = SharpMap.Forms.MapBox.PreviewModes.Fast;
+      this.mapBox.QueryGrowFactor = 5F;
+      this.mapBox.QueryLayerIndex = 0;
+      this.mapBox.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(210)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
+      this.mapBox.SelectionForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
+      this.mapBox.ShowProgressUpdate = true;
+      this.mapBox.Size = new System.Drawing.Size(652, 396);
+      this.mapBox.TabIndex = 0;
+      this.mapBox.TakeFocusOnHover = true;
+      this.mapBox.Text = "mapBox";
+      this.mapBox.WheelZoomMagnitude = -2D;
+      this.mapBox.MouseMove += new SharpMap.Forms.MapBox.MouseEventHandler(this.mapBox_MouseMove);
+      this.mapBox.MouseDown += new SharpMap.Forms.MapBox.MouseEventHandler(this.mapBox_MouseDown);
+      this.mapBox.MouseUp += new SharpMap.Forms.MapBox.MouseEventHandler(this.mapBox_MouseUp);
+      // 
+      // transportLayersListBox
+      // 
+      this.transportLayersListBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
+      this.transportLayersListBox.FormattingEnabled = true;
+      this.transportLayersListBox.HorizontalScrollbar = true;
+      this.transportLayersListBox.Location = new System.Drawing.Point(6, 105);
+      this.transportLayersListBox.Name = "transportLayersListBox";
+      this.transportLayersListBox.Size = new System.Drawing.Size(172, 108);
+      this.transportLayersListBox.TabIndex = 1;
+      this.transportLayersListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.vectorLayerNamesListBox_DrawItem);
+      this.transportLayersListBox.SelectedIndexChanged += new System.EventHandler(this.vectorLayerNamesListBox_SelectedIndexChanged);
+      // 
+      // utilizationLayersListBox
+      // 
+      this.utilizationLayersListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left)));
+      this.utilizationLayersListBox.FormattingEnabled = true;
+      this.utilizationLayersListBox.HorizontalScrollbar = true;
+      this.utilizationLayersListBox.Items.AddRange(new object[] {
+            "StrawPotentials",
+            "StrawUtilizations",
+            "StrawConverterCapacities"});
+      this.utilizationLayersListBox.Location = new System.Drawing.Point(6, 232);
+      this.utilizationLayersListBox.Name = "utilizationLayersListBox";
+      this.utilizationLayersListBox.Size = new System.Drawing.Size(172, 69);
+      this.utilizationLayersListBox.TabIndex = 0;
+      this.utilizationLayersListBox.SelectedIndexChanged += new System.EventHandler(this.valueLayerNamesListBox_SelectedIndexChanged);
+      // 
+      // regionNameLabel
+      // 
+      this.regionNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.regionNameLabel.Location = new System.Drawing.Point(3, 323);
+      this.regionNameLabel.MaximumSize = new System.Drawing.Size(500, 13);
+      this.regionNameLabel.Name = "regionNameLabel";
+      this.regionNameLabel.Size = new System.Drawing.Size(175, 12);
+      this.regionNameLabel.TabIndex = 8;
+      this.regionNameLabel.Text = "AT111";
+      this.regionNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // regionDescriptionLabel
+      // 
+      this.regionDescriptionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.regionDescriptionLabel.Location = new System.Drawing.Point(3, 307);
+      this.regionDescriptionLabel.Margin = new System.Windows.Forms.Padding(3);
+      this.regionDescriptionLabel.MaximumSize = new System.Drawing.Size(500, 13);
+      this.regionDescriptionLabel.Name = "regionDescriptionLabel";
+      this.regionDescriptionLabel.Size = new System.Drawing.Size(175, 13);
+      this.regionDescriptionLabel.TabIndex = 7;
+      this.regionDescriptionLabel.Text = "Vienna";
+      this.regionDescriptionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // qualityLabel
+      // 
+      this.qualityLabel.AutoSize = true;
+      this.qualityLabel.Location = new System.Drawing.Point(3, 3);
+      this.qualityLabel.Margin = new System.Windows.Forms.Padding(3);
+      this.qualityLabel.Name = "qualityLabel";
+      this.qualityLabel.Size = new System.Drawing.Size(83, 13);
+      this.qualityLabel.TabIndex = 11;
+      this.qualityLabel.Text = "Solution Quality:";
+      // 
+      // feedstockCostsLabel
+      // 
+      this.feedstockCostsLabel.AutoSize = true;
+      this.feedstockCostsLabel.Location = new System.Drawing.Point(3, 22);
+      this.feedstockCostsLabel.Margin = new System.Windows.Forms.Padding(3);
+      this.feedstockCostsLabel.Name = "feedstockCostsLabel";
+      this.feedstockCostsLabel.Size = new System.Drawing.Size(128, 13);
+      this.feedstockCostsLabel.TabIndex = 12;
+      this.feedstockCostsLabel.Text = "Feedstock Acq. [Mio€/a]:";
+      // 
+      // transportCostsLabel
+      // 
+      this.transportCostsLabel.AutoSize = true;
+      this.transportCostsLabel.Location = new System.Drawing.Point(3, 41);
+      this.transportCostsLabel.Margin = new System.Windows.Forms.Padding(3);
+      this.transportCostsLabel.Name = "transportCostsLabel";
+      this.transportCostsLabel.Size = new System.Drawing.Size(98, 13);
+      this.transportCostsLabel.TabIndex = 13;
+      this.transportCostsLabel.Text = "Transport [Mio€/a]:";
+      // 
+      // optimizeTransportsButton
+      // 
+      this.optimizeTransportsButton.Location = new System.Drawing.Point(189, 3);
+      this.optimizeTransportsButton.Name = "optimizeTransportsButton";
+      this.optimizeTransportsButton.Size = new System.Drawing.Size(120, 23);
+      this.optimizeTransportsButton.TabIndex = 14;
+      this.optimizeTransportsButton.Text = "Optimize Transports";
+      this.optimizeTransportsButton.UseVisualStyleBackColor = true;
+      this.optimizeTransportsButton.Click += new System.EventHandler(this.optimizeTransportsButton_Click);
+      // 
+      // optimizeUtilizationsButton
+      // 
+      this.optimizeUtilizationsButton.Location = new System.Drawing.Point(315, 3);
+      this.optimizeUtilizationsButton.Name = "optimizeUtilizationsButton";
+      this.optimizeUtilizationsButton.Size = new System.Drawing.Size(120, 23);
+      this.optimizeUtilizationsButton.TabIndex = 15;
+      this.optimizeUtilizationsButton.Text = "Optimize Utilizations";
+      this.optimizeUtilizationsButton.UseVisualStyleBackColor = true;
+      this.optimizeUtilizationsButton.Click += new System.EventHandler(this.optimizeUtilizationsButton_Click);
+      // 
+      // statusStrip
+      // 
+      this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.toolStripStatusLabel});
+      this.statusStrip.Location = new System.Drawing.Point(0, 430);
+      this.statusStrip.Name = "statusStrip";
+      this.statusStrip.Size = new System.Drawing.Size(844, 22);
+      this.statusStrip.TabIndex = 16;
+      this.statusStrip.Text = "statusStrip";
+      // 
+      // toolStripStatusLabel
+      // 
+      this.toolStripStatusLabel.Name = "toolStripStatusLabel";
+      this.toolStripStatusLabel.Size = new System.Drawing.Size(28, 17);
+      this.toolStripStatusLabel.Text = "Info";
+      // 
+      // costPerFuelLabel
+      // 
+      this.costPerFuelLabel.AutoSize = true;
+      this.costPerFuelLabel.Location = new System.Drawing.Point(3, 60);
+      this.costPerFuelLabel.Margin = new System.Windows.Forms.Padding(3);
+      this.costPerFuelLabel.Name = "costPerFuelLabel";
+      this.costPerFuelLabel.Size = new System.Drawing.Size(130, 13);
+      this.costPerFuelLabel.TabIndex = 17;
+      this.costPerFuelLabel.Text = "Transport Fuel Costs [€/t]:";
+      // 
+      // transportInfoLabel
+      // 
+      this.transportInfoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.transportInfoLabel.Location = new System.Drawing.Point(3, 335);
+      this.transportInfoLabel.Name = "transportInfoLabel";
+      this.transportInfoLabel.Size = new System.Drawing.Size(175, 92);
+      this.transportInfoLabel.TabIndex = 18;
+      this.transportInfoLabel.Text = "Transport";
+      // 
+      // BioBoostCompoundSolutionEditor
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.transportInfoLabel);
+      this.Controls.Add(this.costPerFuelLabel);
+      this.Controls.Add(this.statusStrip);
+      this.Controls.Add(this.optimizeUtilizationsButton);
+      this.Controls.Add(this.optimizeTransportsButton);
+      this.Controls.Add(this.transportCostsLabel);
+      this.Controls.Add(this.feedstockCostsLabel);
+      this.Controls.Add(this.qualityLabel);
+      this.Controls.Add(this.regionDescriptionLabel);
+      this.Controls.Add(this.regionNameLabel);
+      this.Controls.Add(this.utilizationLayersListBox);
+      this.Controls.Add(this.transportLayersListBox);
+      this.Controls.Add(this.mapBox);
+      this.Controls.Add(vectorLayersLabel);
+      this.Controls.Add(valueLayersLabel);
+      this.Name = "BioBoostCompoundSolutionEditor";
+      this.Size = new System.Drawing.Size(844, 452);
+      this.statusStrip.ResumeLayout(false);
+      this.statusStrip.PerformLayout();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private SharpMap.Forms.MapBox mapBox;
+    private System.Windows.Forms.ListBox transportLayersListBox;
+    private System.Windows.Forms.ListBox utilizationLayersListBox;
+    private System.Windows.Forms.Label regionNameLabel;
+    private System.Windows.Forms.Label regionDescriptionLabel;
+    private System.Windows.Forms.Label qualityLabel;
+    private System.Windows.Forms.Label feedstockCostsLabel;
+    private System.Windows.Forms.Label transportCostsLabel;
+    private System.Windows.Forms.Button optimizeTransportsButton;
+    private System.Windows.Forms.Button optimizeUtilizationsButton;
+    private System.Windows.Forms.StatusStrip statusStrip;
+    private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel;
+    private System.Windows.Forms.Label costPerFuelLabel;
+    private System.Windows.Forms.Label transportInfoLabel;
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.cs	(revision 13072)
@@ -0,0 +1,789 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using System.Runtime.Remoting.Messaging;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Windows.Forms.VisualStyles;
+using System.Xml.Schema;
+using GeoAPI.Geometries;
+using HeuristicLab.BioBoost.Data;
+using HeuristicLab.BioBoost.Evaluators;
+using HeuristicLab.BioBoost.ProblemDescription;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.BioBoost.Utils;
+using HeuristicLab.BioBoost.Views.MapViews;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+using NetTopologySuite.Geometries;
+using SharpMap;
+using SharpMap.Data;
+using SharpMap.Forms;
+using SharpMap.Layers;
+using SharpMap.Rendering.Decoration;
+using SharpMap.Rendering.Decoration.ScaleBar;
+using Point = System.Drawing.Point;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof(BioBoostCompoundSolution))]
+  public partial class BioBoostCompoundSolutionEditor : ItemView {
+
+    private readonly GradientLegend utilizationLegend;
+
+    private SharpMap.Rendering.Thematics.ColorBlend vectorColorBlend =
+      new SharpMap.Rendering.Thematics.ColorBlend(new[] {
+        Color.FromArgb(0, 0, 255),
+        Color.FromArgb(128, 0, 128),
+        Color.FromArgb(255, 0, 0),
+      }, new[] { 0f, .5f, 1f });
+
+    public const string AllRegionsName = "All";
+
+    public new BioBoostCompoundSolution Content {
+      get { return (BioBoostCompoundSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public BioBoostCompoundSolutionEditor() {
+      InitializeComponent();
+
+      mapBox.Map.Decorations.Add(new ScaleBar {
+        Anchor = MapDecorationAnchor.RightBottom,
+        BarColor1 = Color.White,
+        BarColor2 = Color.Black,
+        BarStyle = ScaleBarStyle.Meridian,
+        MapUnit = (int)Unit.Degree,
+        BarUnit = (int)Unit.Kilometer,
+      });
+
+      utilizationLegend = new GradientLegend();
+      mapBox.Map.Decorations.Add(utilizationLegend);
+      mapBox.Map.Decorations.Add(new NorthArrow());
+      mapBox.ActiveTool = MapBox.Tools.None;
+    }
+
+
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      ReadOnly = Locked || Content == null;
+      mapBox.Enabled = !Locked && Content != null;
+      transportLayersListBox.Enabled = !Locked && Content != null;
+      utilizationLayersListBox.Enabled = !Locked && Content != null;
+    }
+
+    #region content events
+    protected override void OnContentChanged() {
+      if (InvokeRequired) {
+        Invoke((Action)OnContentChanged);
+      } else {
+        base.OnContentChanged();
+        if (Content == null) {
+          Clear();
+        } else {
+          Update();
+        }
+      }
+    }
+    protected override void DeregisterContentEvents() {
+      Content.SolutionChanged -= SolutionChanged;
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.SolutionChanged += SolutionChanged;
+    }
+
+    private void SolutionChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler<EventArgs>(SolutionChanged), sender, e);
+      } else {
+        Update();
+      }
+    }
+    #endregion
+
+
+    #region Main Logic
+    private void Clear() {
+      qualityLabel.Text = string.Empty;
+      feedstockCostsLabel.Text = string.Empty;
+      transportCostsLabel.Text = string.Empty;
+      utilizationLayersListBox.Items.Clear();
+      transportLayersListBox.Items.Clear();
+      mapBox.Map.Layers.Clear(); // only two layers are active at any time (representing the layers selected in the list boxes on the left)
+    }
+
+    private void Update() {
+      // store currently selected items
+      var selectedValueLayerName = GetSelectedLayer(utilizationLayersListBox);
+      var selectedVectorLayerName = GetSelectedLayer(transportLayersListBox);
+
+      // clear everything
+      Clear();
+      FillQualityInformation();
+      FillValueLayersListBox();
+      FillVectorLayersListBox();
+
+      // restore selection if possible
+      // when we couldn't restore the value or vector layer then there has been a larger change (unexpected) and we need to reset the zoom level
+      // this also makes sure that the zoom level is set correctly when the solution is initially displayed
+      if (!TrySetSelectedLayer(utilizationLayersListBox, selectedValueLayerName) |
+          !TrySetSelectedLayer(transportLayersListBox, selectedVectorLayerName)) {
+        ResetZoom();
+      }
+      mapBox.Refresh();
+    }
+
+    private void FillQualityInformation() {
+      qualityLabel.Text = string.Format("Solution quality: {0:F4}", Content.Quality);
+      feedstockCostsLabel.Text = string.Format("Feedstock [Mio€/a]: {0:N1}", Content.TotalFeedstockCosts / 1E6);
+      transportCostsLabel.Text = string.Format("Transport [Mio€/a]: {0:N1}", Content.TotalTransportCosts / 1E6);
+      costPerFuelLabel.Text = string.Format("Transport Fuel Costs [€/t]: {0:N1}", Content.TotalCosts / Content.TotalTransportFuelAmount);
+    }
+
+
+    private void FillValueLayersListBox() {
+      // we only add items for layers that we are allowed to change (layers that correspond to a vector in the representation)
+      // add utilizations for all feedstock
+      utilizationLayersListBox.BeginUpdate();
+      foreach (var pair in Content.UtilizationVectors) {
+        var newItem = new ListBoxItem<double[]> {
+          Color = Color.White,
+          Text = pair.Item1,
+          Value = pair.Item2
+        };
+        utilizationLayersListBox.Items.Add(newItem);
+      }
+      utilizationLayersListBox.EndUpdate();
+    }
+
+    private void FillVectorLayersListBox() {
+      // we only add items for vectors that we are allowed to change
+      // add transport vector layers for all products
+      transportLayersListBox.BeginUpdate();
+      int i = 0;
+      int n = Content.TransportVectors.Count();
+      foreach (var pair in Content.TransportVectors) {
+        var newItem = new ListBoxItem<int[]> {
+          Color = vectorColorBlend.GetColor(1f * i++ / (float)n),
+          Text = pair.Item1,
+          Value = pair.Item2
+        };
+        transportLayersListBox.Items.Add(newItem);
+      }
+      transportLayersListBox.EndUpdate();
+    }
+
+    private void UpdateMapLayers() {
+      mapBox.Map.Layers.Clear();
+      AddSelectedValueLayer(); // values first ...
+      AddSelectedVectorLayer(); // ... then vectors (because they need to be drawn last)
+      AddWorstTransportsVectorLayer();
+      mapBox.Refresh();
+    }
+
+    private void AddWorstTransportsVectorLayer() {
+      var geom = Content.Geometry;
+      var locs = Content.LocationNames;
+      var selectedProduct = GetSelectedLayer(transportLayersListBox);
+      if (selectedProduct == string.Empty) return;
+      int[] worstTransports = new int[locs.Length];
+      for (int i = 0; i < worstTransports.Length; i++) {
+        worstTransports[i] = -1;
+      }
+      foreach (var transport in CalcNonDominatedTransports()) {
+        if (transport.Product != selectedProduct) continue;
+        worstTransports[transport.SrcRegionIdx] = transport.DestRegionIdx;
+      }
+
+      var allTransports = Content.Transports.Where(t => t.Product == selectedProduct).ToArray();
+
+      // for all regions find the matching transport (if there is one)
+      var transportAmounts = locs
+        .Select(loc => allTransports.FirstOrDefault(t => t.SrcRegion == loc))
+        .Select(trans => trans == null ? 0.0 : trans.Amount)
+        .ToArray();
+
+      var generator = new LazyVectorLayerGenerator(geom, locs, worstTransports, transportAmounts, Color.Red, "Worst Transports");
+
+      mapBox.Map.Layers.Add(generator.Layer);
+    }
+
+
+    private void AddSelectedVectorLayer() {
+      var selectedVectorLayerItem = transportLayersListBox.SelectedItem as ListBoxItem<int[]>;
+      if (selectedVectorLayerItem == null) return;
+
+      var selectedProduct = GetSelectedLayer(transportLayersListBox);
+
+      var geom = Content.Geometry;
+      var locs = Content.LocationNames;
+
+      var allTranports = Content.Transports.Where(t => t.Product == selectedProduct).ToArray();
+
+      // foreach location find the transport amounts (if there is any)
+      var amounts = locs
+        .Select(loc => allTranports.FirstOrDefault(trans => trans.SrcRegion == loc))
+        .Select(trans => trans == null ? 0.0 : trans.Amount)
+        .ToArray();
+
+      var generator = new LazyVectorLayerGenerator(geom, locs, selectedVectorLayerItem.Value, amounts, selectedVectorLayerItem.Color, "Transports");
+
+      mapBox.Map.Layers.Add(generator.Layer);
+    }
+
+    private void AddSelectedValueLayer() {
+      var selectedValueLayerItem = utilizationLayersListBox.SelectedItem as ListBoxItem<double[]>;
+      if (selectedValueLayerItem == null) return;
+
+      var geom = Content.Geometry;
+      var locs = Content.LocationNames;
+
+      var generator = new LazyValueLayerGenerator(geom, locs, selectedValueLayerItem.Value, "Utilizations");
+
+      mapBox.Map.Layers.Add(generator.Layer);
+    }
+
+
+    // clicking on the map changes the underlying solution and causes a reevaluation
+    // this is called by the mouse-up event handler
+    private async void DispatchMouseUp(string startRegion, string endRegion, Tuple<string, string> arrow, Point mousePos) {
+      // some operations on the content might fail ... show an error dialog in this case
+      try {
+        if (arrow != null && startRegion == endRegion) {
+          // an vector was clicked => remove it
+          Content.SetTransport(GetSelectedLayer(transportLayersListBox), arrow.Item1, arrow.Item1);
+          // remove the vector
+        } else if (startRegion != string.Empty && endRegion == startRegion &&
+                   Util.Distance(startPos, mousePos) < 4) {
+          // no vector but
+          // region was clicked (no dragging) => update utilization
+          var currentUtil = Content.GetUtilization(GetSelectedLayer(utilizationLayersListBox), endRegion);
+          var newUtil = await ShowTrackBar(new Point(mousePos.X - 10, mousePos.Y - 10), currentUtil);
+          Content.SetUtilization(GetSelectedLayer(utilizationLayersListBox), endRegion, newUtil);
+        } else if (startRegion != string.Empty && endRegion != string.Empty) {
+          // we dragged from one region to another (possibly the same region
+          Content.SetTransport(GetSelectedLayer(transportLayersListBox), startRegion, endRegion);
+        }
+      } catch (SystemException e) {
+        var dialog = new ErrorDialog(e);
+        dialog.ShowDialog(this);
+      }
+    }
+
+    public void OptimizeTransports() {
+      // FullLocalSearchForTransports();
+      // NearestPlantLocalSearchForTransports();
+      PruneLongAndSmallTransports();
+    }
+
+    private IEnumerable<BioBoostCompoundSolution.TransportInfo> CalcNonDominatedTransports() {
+      var transports = Content.Transports.ToArray();
+      var transportDistances = transports.Select(t => t.Distance).ToArray();
+      var transportAmounts = transports.Select(t => t.Amount).ToArray();
+
+      for (int i = 0; i < transports.Length; i++) {
+        if (!IsDominated(i, transportDistances, transportAmounts)) {
+          yield return transports[i];
+        }
+      }
+    }
+
+    private void PruneLongAndSmallTransports() {
+
+      var nonDominatedTransports = CalcNonDominatedTransports().ToArray();
+
+      var oldQ = Content.Quality;
+      var curQ = Content.Quality;
+      var curContent = (BioBoostCompoundSolution)Content.Clone();
+      foreach (var transport in nonDominatedTransports) {
+        curContent.SetTransport(transport.Product, transport.SrcRegionIdx, transport.SrcRegionIdx);
+      }
+      curQ = curContent.Quality;
+
+      SetStatusInfo(string.Format("Deleted {0} transports. Total quality improvement: {1:F4}", nonDominatedTransports.Length,
+        curQ - Content.Quality));
+      Content.UpdateTo(curContent);
+    }
+
+    private bool IsDominated(int idx, double[] transportDistances, double[] transportAmounts) {
+      // check if there is any other transport that has a larger distance and a smaller amount
+      var dominatingIdx =
+        Enumerable.Range(0, transportDistances.Length)
+        .Where((otherIdx) => idx != otherIdx)
+        .Where((otherIdx) => transportDistances[otherIdx] > transportDistances[idx])
+        .Where((otherIdx) => transportAmounts[otherIdx] < transportAmounts[idx]);
+      return (dominatingIdx.Any());
+    }
+
+    /*
+    private void NearestPlantLocalSearchForTransports() {
+      // for each transport check if we can reroute it to a nearer plant (with minor loss in quality 1%)
+      const double maxRelativeQualityChange = -0.001;
+      var oldQ = Content.Quality;
+      var curQ = Content.Quality;
+      var curContent = (BioBoostCompoundSolution)Content.Clone();
+      // TODO: assumes that there is only one distance matrix and all products are transported using this matrix!!
+      Debug.Assert(Content.ProblemDataReference.Parameters.Count(p => p.Name.EndsWith("DistanceMatrix")) == 1);
+      var distanceMatrix = (DistanceMatrix)Content.ProblemDataReference.Parameters.First(p => p.Name.EndsWith("DistanceMatrix")).ActualValue;
+
+      // for each product a list of possible targets (possible targets stay fixed in optimization)
+      var curTransportTargets = curContent.TransportVectors
+        .Select(kvp => new KeyValuePair<string, int[]>(kvp.Item1, kvp.Item2.Distinct().Where(i => i >= 0).OrderBy(t => t).ToArray()))
+        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
+
+      // for each product and for each region a list of the max 5 nearest plants
+      var nearestPlantIdx = new Dictionary<string, int[][]>();
+      foreach (var product in curTransportTargets.Keys) {
+        nearestPlantIdx.Add(product, new int[curContent.LocationNames.Length][]);
+        var nIdx = nearestPlantIdx[product];
+        for (int src = 0; src < nIdx.Length; src++) {
+          var plantsByDistance =
+            curTransportTargets[product].OrderBy(possibleTarget => distanceMatrix[src, possibleTarget]);
+          var nPlants = Math.Min(plantsByDistance.Count(), 3);
+          nIdx[src] = plantsByDistance.Take(nPlants).ToArray();
+        }
+      }
+
+      // generate possible changes
+      // either change the transport to the nearest existing plant ...
+      // ... or if the transport is within the same region then to the second nearest plant (reduces plants)
+      var changes = new List<Tuple<string, int, int>>(); // product x source x dest
+      foreach (var kvp in curContent.TransportVectors) {
+        var prod = kvp.Item1;
+        var curDest = kvp.Item2;
+        for (int src = 0; src < curDest.Length; src++) {
+          var dest = curDest[src];
+          if (dest == -1)
+            continue; // don't allow transports if the current transport target is -1 
+          foreach (var alternativeDest in nearestPlantIdx[prod][src]) {
+            if (alternativeDest != dest)
+              changes.Add(Tuple.Create(prod, src, alternativeDest));
+          }
+        }
+      }
+
+      var improvements = new List<double>();
+      // evalute changes (full evaluation)
+      for (int i = 0; i < changes.Count; i++) {
+        // apply each change in turn to a clone of the solution and check the change in quality
+        var change = changes[i];
+        var tmpContent = (BioBoostCompoundSolution)curContent.Clone();
+        tmpContent.SetTransport(change.Item1, change.Item2, change.Item3); // product, src, dest
+        improvements.Add(tmpContent.Quality - curQ); // if quality after change is worse than current quality improvement is negative
+      }
+
+      var sortedChanges =
+        changes.Zip(improvements, (change, improvement) => new { change, improvement })
+        .OrderByDescending(p => p.improvement) // positive improvements first
+        .ToArray();
+
+      int changeCount = 0;
+      int changeIdx = 0;
+
+      bool changed = true; // has there been a change in this iteration
+      // while there is a total deterioation not worse than -1%
+      var totalChange = 0.0;
+      while (changeIdx < sortedChanges.Length && changed && totalChange > (oldQ * maxRelativeQualityChange)) {
+        changed = false;
+        var change = sortedChanges[changeIdx].change;
+        var improvement = sortedChanges[changeIdx].improvement;
+        // and each step is not worse than -1%
+        if (improvement > curQ * maxRelativeQualityChange) {
+          changeCount++;
+          totalChange += improvement;
+          curContent.SetTransport(change.Item1, change.Item2, change.Item3); // product, src, dest
+          curQ = curContent.Quality; // update current quality
+          changed = true;
+        }
+        changeIdx++;
+      }
+
+      Content.UpdateTo(curContent);
+      SetStatusInfo(string.Format("Changed {0} transports. Total quality improvement: {1:F4}", changeCount,
+        Content.Quality - oldQ));
+    }
+    */
+
+    /*
+    private void FullLocalSearchForTransports() {
+      // for each transport check if we can reroute the transport to any other location (which already is a transport target for this product type)
+      // local search using best improvement
+      double oldQ;
+      var curQ = Content.Quality;
+      var curContent = (BioBoostCompoundSolution)Content.Clone();
+
+      // for each product a list of possible targets (possible targets stay fixed in optimization)
+      var curTransportTargets = curContent.TransportVectors
+        .Select(kvp => new KeyValuePair<string, int[]>(kvp.Item1, kvp.Item2.Distinct().OrderBy(t => t).ToArray()))
+        .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
+
+      int changeCount = 0;
+      do {
+        // store current quality (to check if we found an improvement)
+        oldQ = curQ;
+
+        // generate possible changes
+        var changes = new List<Tuple<string, int, int>>(); // product x source x dest
+        foreach (var kvp in curContent.TransportVectors) {
+          var prod = kvp.Item1;
+          var curDest = kvp.Item2;
+          foreach (var alternativeDest in curTransportTargets[prod]) {
+            if (alternativeDest == -1) continue; // don't allow transport to new locations (without plants)
+            for (int src = 0; src < curDest.Length; src++) {
+              var dest = curDest[src];
+              if (dest == -1) continue; // don't allow transports if the current transport target is -1 (TODO: check with erik)
+
+              if (dest != alternativeDest) {
+                changes.Add(Tuple.Create(prod, src, alternativeDest));
+              }
+            }
+          }
+        }
+
+        // evalute changes (full evaluation)
+        var bestImprovement = double.NegativeInfinity;
+        var bestChangeIdx = -1;
+        for (int i = 0; i < changes.Count; i++) {
+          // apply each change in turn to a clone of the solution and check the change in quality
+          var change = changes[i];
+          var tmpContent = (BioBoostCompoundSolution)curContent.Clone();
+          tmpContent.SetTransport(change.Item1, change.Item2, change.Item3); // product, src, dest
+          var improvement = tmpContent.Quality - curQ;
+          if (improvement > bestImprovement) {
+            bestImprovement = improvement;
+            bestChangeIdx = i;
+          }
+        }
+        if (bestImprovement > 0) {
+          changeCount++;
+          var bestChange = changes[bestChangeIdx];
+          curContent.SetTransport(bestChange.Item1, bestChange.Item2, bestChange.Item3); // product, src, dest
+          curQ = curContent.Quality; // update current quality
+        }
+
+        // apply best change
+      } while (oldQ < curQ);
+
+      SetStatusInfo(string.Format("Changed {0} transports. Total quality improvement: {1:F4}", changeCount,
+        curQ - Content.Quality));
+      Content.UpdateTo(curContent);
+    }*/
+
+
+    public void OptimizeUtilizations() {
+      double oldQ;
+      var curQ = Content.Quality;
+      var curContent = (BioBoostCompoundSolution)Content.Clone();
+      int changeCount = 0;
+      do {
+        oldQ = curQ;
+
+        // for each product and region check if the quality increases if we set the utilization to zero
+        // local search using first improvement
+        var changes = new List<Tuple<string, int, double>>(); // product x region x utilization
+        foreach (var pair in curContent.UtilizationVectors) {
+          var prod = pair.Item1;
+          var util = pair.Item2;
+          for (int regIdx = 0; regIdx < util.Length; regIdx++) {
+            if (util[regIdx] > 0) {
+              changes.Add(Tuple.Create(prod, regIdx, 0.0));
+            }
+          }
+        }
+
+        var bestImprovement = double.NegativeInfinity;
+        var bestChange = changes.First();
+        foreach (var change in changes) {
+          var tmpContent = (BioBoostCompoundSolution)curContent.Clone();
+          tmpContent.SetUtilization(change.Item1, change.Item2, change.Item3);
+          var newQ = tmpContent.Quality;
+          var improvement = newQ - curQ; // positive improvements (new quality is higher than current quality
+          if (improvement > bestImprovement) {
+            bestImprovement = improvement;
+            bestChange = change;
+          }
+        }
+
+        // apply if we found a possible improvement
+        if (bestImprovement > 0) {
+          curContent.SetUtilization(bestChange.Item1, bestChange.Item2, bestChange.Item3);
+          curQ = curContent.Quality;
+          changeCount++;
+        }
+      } while (oldQ < curQ);
+
+      SetStatusInfo(string.Format("Changed {0} utilizations. Total quality improvement: {1:F4}", changeCount,
+        curQ - Content.Quality));
+      Content.UpdateTo(curContent);
+    }
+
+    private void SetStatusInfo(string message) {
+      if (InvokeRequired) {
+        Invoke((Action<string>)SetStatusInfo, message);
+      } else {
+        toolStripStatusLabel.Text = message;
+      }
+    }
+
+    private void UpdateTransportInfo(Tuple<string, string> vector) {
+      transportInfoLabel.Text = string.Empty; // clear
+      if (vector != null) {
+        var transportProduct = GetSelectedLayer(transportLayersListBox);
+        var transportInfo =
+          Content.Transports.FirstOrDefault(
+            info => info.Product == transportProduct && info.SrcRegion == vector.Item1 && info.DestRegion == vector.Item2);
+        if (transportInfo != null) {
+
+          var sb = new StringBuilder();
+          sb.AppendFormat("{0} -> {1}", transportInfo.SrcRegion, transportInfo.DestRegion).AppendLine();
+          sb.AppendFormat("{0} (Mode: {1})", transportInfo.Product, transportInfo.Mode).AppendLine();
+          sb.AppendFormat("{0:N0} kt km", transportInfo.Distance * transportInfo.Amount / 1000.0).AppendLine();
+          sb.AppendFormat("{0:N1} kt {1:N0} km", transportInfo.Amount / 1000.0, transportInfo.Distance);
+          transportInfoLabel.Text = sb.ToString();
+        }
+      }
+    }
+    #endregion
+
+
+
+    #region Event Handlers (child controls)
+    private void vectorLayerNamesListBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateMapLayers();
+    }
+
+    private void valueLayerNamesListBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateMapLayers();
+    }
+
+    private void optimizeTransportsButton_Click(object sender, EventArgs e) {
+      using (BackgroundWorker bg = new BackgroundWorker()) {
+        MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>().AddOperationProgressToView(this, "Optimizing Transports...");
+        bg.DoWork += (o, a) => OptimizeTransports();
+        bg.RunWorkerCompleted += (o, a) => MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>().RemoveOperationProgressFromView(this);
+        bg.RunWorkerAsync();
+      }
+    }
+
+    private void optimizeUtilizationsButton_Click(object sender, EventArgs e) {
+      using (BackgroundWorker bg = new BackgroundWorker()) {
+        MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>().AddOperationProgressToView(this, "Optimizing Utilizations...");
+        bg.DoWork += (o, a) => OptimizeUtilizations();
+        bg.RunWorkerCompleted += (o, a) => MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>().RemoveOperationProgressFromView(this);
+        bg.RunWorkerAsync();
+      }
+    }
+    #endregion
+
+    #region mouse events
+    // TODO: it should be possible to allow panning and drawing arrows at the same time by implementing a CustomTool
+    private void mapBox_MouseMove(Coordinate worldPos, MouseEventArgs imagePos) {
+      var nuts_id = GetRegionAtWorldPos(worldPos);
+      var nuts_name = GetRegionDescription(nuts_id);
+      regionNameLabel.Text = nuts_id;
+      regionDescriptionLabel.Text = nuts_name;
+      mapBox.Cursor = String.IsNullOrEmpty(nuts_id) ? Cursors.Default : Cursors.Hand;
+      var arrow = GetArrowAtWorldPos(worldPos);
+      UpdateTransportInfo(arrow);
+    }
+
+    private Point startPos = new Point(0, 0);
+    private Coordinate startWorldPos;
+    private void mapBox_MouseDown(Coordinate worldPos, MouseEventArgs mouseEventArgs) {
+      if (mouseEventArgs.Button == MouseButtons.Left) {
+        startPos = mouseEventArgs.Location;
+        startWorldPos = worldPos;
+      }
+    }
+
+    private void mapBox_MouseUp(Coordinate endWorldPos, MouseEventArgs mousePos) {
+      if (mousePos.Button == MouseButtons.Left) {
+        var arrow = GetArrowAtWorldPos(startWorldPos);
+
+        var startRegion = GetRegionAtWorldPos(startWorldPos);
+        var endRegion = GetRegionAtWorldPos(endWorldPos);
+
+        DispatchMouseUp(startRegion, endRegion, arrow, mousePos.Location);
+      }
+    }
+
+    // custom drawing method for vector list box (for coloring of layers)
+    private void vectorLayerNamesListBox_DrawItem(object sender, DrawItemEventArgs e) {
+      var item = transportLayersListBox.Items[e.Index];
+      var listBoxItem = item as ListBoxItem<int[]>;
+      var backColor = listBoxItem.Color;
+      var foreColor = Color.White;
+
+      using (var backBrush = new SolidBrush(backColor)) {
+        e.Graphics.FillRectangle(backBrush, e.Bounds);
+      }
+      using (var foreBrush = new SolidBrush(foreColor)) {
+        e.Graphics.DrawString(
+          listBoxItem.Text,
+          transportLayersListBox.Font, foreBrush, e.Bounds);
+      }
+    }
+    #endregion
+
+    #region drag-and-drop of problem data
+
+    private bool dropAllowed = false;
+    protected override void OnDragDrop(DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        var problemData = (BioBoostProblemData)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        Content.ProblemDataReference = (BioBoostProblemData)problemData.Clone();
+      }
+    }
+
+    protected override void OnDragEnter(DragEventArgs e) {
+      var problemData = (BioBoostProblemData)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      dropAllowed = !ReadOnly && !Locked && problemData != null;
+    }
+
+    protected override void OnDragOver(DragEventArgs e) {
+      e.Effect = dropAllowed ?
+        DragDropEffects.Copy :
+        DragDropEffects.None;
+    }
+
+    #endregion
+
+
+    #region Auxiliar Methods
+    private Task<double> ShowTrackBar(Point location, double value) {
+
+      var wh = new AutoResetEvent(false);
+      var tb = new TrackBar {
+        TickStyle = TickStyle.None,
+        Minimum = 0,
+        Maximum = 100,
+        Value = (int)Math.Round(value * 100),
+        Location = location
+      };
+      var label = new Label();
+      label.Location = new Point(location.X, location.Y - label.Height);
+      label.Text = string.Format("Utilization: {0:F2}", value);
+      label.Width = tb.Width;
+
+      mapBox.Controls.Add(tb);
+      mapBox.Controls.Add(label);
+
+      tb.Focus();
+      tb.ValueChanged += (sender, args) => {
+        value = tb.Value / 100.0;
+        label.Text = string.Format("Utilization: {0:F2}", value);
+      };
+      tb.LostFocus += (sender, args) => {
+        mapBox.Controls.Remove(tb);
+        mapBox.Controls.Remove(label);
+        wh.Set();
+      };
+
+
+      return Task.Run(() => {
+        wh.WaitOne();
+        wh.Dispose();
+        return value;
+      });
+    }
+
+    // returns the NUTS_ID of the region if it has been hit
+    private string GetRegionAtWorldPos(Coordinate loc) {
+      var ds = new FeatureDataSet();
+      var layer = mapBox.Map.Layers.OfType<VectorLayer>().SingleOrDefault(l => l.LayerName == "Utilizations");
+      if (layer == null) return string.Empty;
+
+      layer.ExecuteIntersectionQuery(new NetTopologySuite.Geometries.Point(loc), ds);
+      return (from FeatureDataRow row in ds.Tables[0]
+              select row["NUTS_ID"] as string).FirstOrDefault() ?? string.Empty; // default is string.Empty
+    }
+
+    // returns the source and target NUTS_ID (Tuple(src, trgt)) for an vector if it has been hit
+    private Tuple<string, string> GetArrowAtWorldPos(Coordinate loc) {
+      var ds = new FeatureDataSet();
+      var layer = mapBox.Map.Layers.OfType<VectorLayer>().SingleOrDefault(l => l.LayerName == "Transports");
+      if (layer == null) return null;
+
+      var rect = new Coordinate[5];
+      var delta = mapBox.Map.PixelWidth * 2; // for bounding box arount the click point
+      rect[0] = new Coordinate(loc.X - delta, loc.Y - delta);
+      rect[1] = new Coordinate(loc.X + delta, loc.Y - delta);
+      rect[3] = new Coordinate(loc.X + delta, loc.Y + delta);
+      rect[2] = new Coordinate(loc.X - delta, loc.Y + delta);
+      rect[4] = new Coordinate(loc.X - delta, loc.Y - delta);
+      layer.ExecuteIntersectionQuery(new NetTopologySuite.Geometries.Polygon(new LinearRing(rect)), ds);
+
+      var arrow = (from FeatureDataRow row in ds.Tables[0]
+                   select Tuple.Create((string)row["NUTS_ID_SRC"], (string)row["NUTS_ID_DEST"])
+        ).FirstOrDefault();
+      return arrow;
+    }
+
+
+    private string GetRegionDescription(string regionName) {
+      if (regionName != null && Content.Geometry.Features.Columns.Contains("name")) {
+        var row = Content.Geometry.Features.Rows.Cast<FeatureDataRow>().FirstOrDefault(r => (string)r["NUTS_ID"] == regionName);
+        if (row != null)
+          return row["name"].ToString();
+      }
+      return string.Empty;
+    }
+
+
+    private void ResetZoom() {
+      if (mapBox.Map.Layers.Count > 0)
+        mapBox.Map.ZoomToExtents();
+      // mapBox.ActiveTool = MapBox.Tools.DrawLine;
+      mapBox.Refresh();
+    }
+
+
+    private string GetSelectedLayer(ListBox listBox) {
+      return
+      listBox.SelectedItem == null ?
+        string.Empty
+        : listBox.SelectedItem.ToString();
+    }
+
+
+    private bool TrySetSelectedLayer(ListBox listBox, string text) {
+      bool success = false;
+      if (string.IsNullOrEmpty(text)) {
+        listBox.SelectedIndex = 0;
+      } else {
+        int selectedIndex = 0;
+        for (int i = 0; i < listBox.Items.Count; i++) {
+          if (listBox.Items[i].ToString() == text) {
+            selectedIndex = i;
+            success = true;
+            break;
+          }
+        }
+        listBox.SelectedIndex = selectedIndex;
+      }
+      return success;
+    }
+    #endregion
+
+    // only necessary for drawing of vector layer elements with color
+    private class ListBoxItem<T> {
+      public Color Color { get; set; }
+      public string Text { get; set; }
+      public T Value { get; set; }
+
+      public override string ToString() {
+        return Text;
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionEditor.resx	(revision 13072)
@@ -0,0 +1,129 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="vectorLayersLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="valueLayersLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.Designer.cs	(revision 13072)
@@ -0,0 +1,438 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostCompoundSolutionView {
+    /// <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)) {
+        runningUpdateMap = false;
+        runningUpdateCosts = false;
+        updateMap.Set();
+        updateCosts.Set();
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.Label valueLayersLabel;
+      System.Windows.Forms.Label vectorLayersLabel;
+      System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("AT111");
+      System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("AT112");
+      System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("AT", new System.Windows.Forms.TreeNode[] {
+            treeNode1,
+            treeNode2});
+      System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("BE112");
+      System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("BE", new System.Windows.Forms.TreeNode[] {
+            treeNode4});
+      System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("All Regions", new System.Windows.Forms.TreeNode[] {
+            treeNode3,
+            treeNode5});
+      this.mapBox = new SharpMap.Forms.MapBox();
+      this.tabControl1 = new System.Windows.Forms.TabControl();
+      this.tabPage1 = new System.Windows.Forms.TabPage();
+      this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+      this.valueLayerValueLabel = new System.Windows.Forms.Label();
+      this.valueLayerNamesListBox = new System.Windows.Forms.ListBox();
+      this.vectorLayerNamesListBox = new System.Windows.Forms.ListBox();
+      this.regionDescriptionLabel = new System.Windows.Forms.Label();
+      this.regionNameLabel = new System.Windows.Forms.Label();
+      this.splitContainer2 = new System.Windows.Forms.SplitContainer();
+      this.regionDetailView = new HeuristicLab.BioBoost.Views.BioBoostRegionDetailView();
+      this.saveMapImageButton = new System.Windows.Forms.Button();
+      this.tabPage2 = new System.Windows.Forms.TabPage();
+      this.bioBoostSolutionCostsView1 = new HeuristicLab.BioBoost.Views.BioBoostSolutionCostsView();
+      this.regionsTreeView = new System.Windows.Forms.TreeView();
+      this.tabPage3 = new System.Windows.Forms.TabPage();
+      this.openSolutionEditorButton = new System.Windows.Forms.Button();
+      this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
+      this.tabPage4 = new System.Windows.Forms.TabPage();
+      this.summaryView = new HeuristicLab.BioBoost.Views.BioBoostSummaryView();
+      valueLayersLabel = new System.Windows.Forms.Label();
+      vectorLayersLabel = new System.Windows.Forms.Label();
+      this.tabControl1.SuspendLayout();
+      this.tabPage1.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+      this.splitContainer1.Panel1.SuspendLayout();
+      this.splitContainer1.Panel2.SuspendLayout();
+      this.splitContainer1.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
+      this.splitContainer2.Panel1.SuspendLayout();
+      this.splitContainer2.Panel2.SuspendLayout();
+      this.splitContainer2.SuspendLayout();
+      this.tabPage2.SuspendLayout();
+      this.tabPage3.SuspendLayout();
+      this.tabPage4.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // valueLayersLabel
+      // 
+      valueLayersLabel.AutoSize = true;
+      valueLayersLabel.Location = new System.Drawing.Point(2, 145);
+      valueLayersLabel.Name = "valueLayersLabel";
+      valueLayersLabel.Size = new System.Drawing.Size(68, 13);
+      valueLayersLabel.TabIndex = 27;
+      valueLayersLabel.Text = "Value Layers";
+      // 
+      // vectorLayersLabel
+      // 
+      vectorLayersLabel.AutoSize = true;
+      vectorLayersLabel.Location = new System.Drawing.Point(6, 5);
+      vectorLayersLabel.Name = "vectorLayersLabel";
+      vectorLayersLabel.Size = new System.Drawing.Size(72, 13);
+      vectorLayersLabel.TabIndex = 26;
+      vectorLayersLabel.Text = "Vector Layers";
+      // 
+      // mapBox
+      // 
+      this.mapBox.ActiveTool = SharpMap.Forms.MapBox.Tools.Pan;
+      this.mapBox.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.mapBox.Cursor = System.Windows.Forms.Cursors.Hand;
+      this.mapBox.FineZoomFactor = 10D;
+      this.mapBox.Location = new System.Drawing.Point(3, 0);
+      this.mapBox.MapQueryMode = SharpMap.Forms.MapBox.MapQueryType.VisibleLayers;
+      this.mapBox.Name = "mapBox";
+      this.mapBox.PanOnClick = false;
+      this.mapBox.PreviewMode = SharpMap.Forms.MapBox.PreviewModes.Fast;
+      this.mapBox.QueryGrowFactor = 5F;
+      this.mapBox.QueryLayerIndex = 0;
+      this.mapBox.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(210)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
+      this.mapBox.SelectionForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
+      this.mapBox.ShowProgressUpdate = true;
+      this.mapBox.Size = new System.Drawing.Size(561, 635);
+      this.mapBox.TabIndex = 0;
+      this.mapBox.TakeFocusOnHover = true;
+      this.mapBox.Text = "mapBox";
+      this.mapBox.WheelZoomMagnitude = -2D;
+      this.mapBox.MouseMove += new SharpMap.Forms.MapBox.MouseEventHandler(this.mapBox_MouseMove);
+      this.mapBox.MouseDown += new SharpMap.Forms.MapBox.MouseEventHandler(this.mapBox_MouseDown);
+      this.mapBox.MouseUp += new SharpMap.Forms.MapBox.MouseEventHandler(this.mapBox_MouseUp);
+      // 
+      // tabControl1
+      // 
+      this.tabControl1.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.tabControl1.Controls.Add(this.tabPage1);
+      this.tabControl1.Controls.Add(this.tabPage2);
+      this.tabControl1.Controls.Add(this.tabPage3);
+      this.tabControl1.Controls.Add(this.tabPage4);
+      this.tabControl1.Location = new System.Drawing.Point(0, 0);
+      this.tabControl1.Name = "tabControl1";
+      this.tabControl1.SelectedIndex = 0;
+      this.tabControl1.Size = new System.Drawing.Size(1114, 682);
+      this.tabControl1.TabIndex = 2;
+      this.tabControl1.Selected += new System.Windows.Forms.TabControlEventHandler(this.tabControl1_Selected);
+      // 
+      // tabPage1
+      // 
+      this.tabPage1.Controls.Add(this.splitContainer1);
+      this.tabPage1.Location = new System.Drawing.Point(4, 22);
+      this.tabPage1.Name = "tabPage1";
+      this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage1.Size = new System.Drawing.Size(1106, 656);
+      this.tabPage1.TabIndex = 0;
+      this.tabPage1.Text = "Map";
+      this.tabPage1.UseVisualStyleBackColor = true;
+      // 
+      // splitContainer1
+      // 
+      this.splitContainer1.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.splitContainer1.Location = new System.Drawing.Point(6, 6);
+      this.splitContainer1.Name = "splitContainer1";
+      // 
+      // splitContainer1.Panel1
+      // 
+      this.splitContainer1.Panel1.Controls.Add(this.valueLayerValueLabel);
+      this.splitContainer1.Panel1.Controls.Add(this.valueLayerNamesListBox);
+      this.splitContainer1.Panel1.Controls.Add(this.vectorLayerNamesListBox);
+      this.splitContainer1.Panel1.Controls.Add(this.regionDescriptionLabel);
+      this.splitContainer1.Panel1.Controls.Add(this.regionNameLabel);
+      this.splitContainer1.Panel1.Controls.Add(valueLayersLabel);
+      this.splitContainer1.Panel1.Controls.Add(vectorLayersLabel);
+      // 
+      // splitContainer1.Panel2
+      // 
+      this.splitContainer1.Panel2.Controls.Add(this.splitContainer2);
+      this.splitContainer1.Size = new System.Drawing.Size(1094, 644);
+      this.splitContainer1.SplitterDistance = 214;
+      this.splitContainer1.TabIndex = 14;
+      // 
+      // valueLayerValueLabel
+      // 
+      this.valueLayerValueLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.valueLayerValueLabel.Location = new System.Drawing.Point(3, 620);
+      this.valueLayerValueLabel.Margin = new System.Windows.Forms.Padding(3);
+      this.valueLayerValueLabel.MaximumSize = new System.Drawing.Size(500, 13);
+      this.valueLayerValueLabel.Name = "valueLayerValueLabel";
+      this.valueLayerValueLabel.Size = new System.Drawing.Size(207, 13);
+      this.valueLayerValueLabel.TabIndex = 28;
+      this.valueLayerValueLabel.Text = "0 €/a";
+      this.valueLayerValueLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // valueLayerNamesListBox
+      // 
+      this.valueLayerNamesListBox.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.valueLayerNamesListBox.FormattingEnabled = true;
+      this.valueLayerNamesListBox.HorizontalScrollbar = true;
+      this.valueLayerNamesListBox.Items.AddRange(new object[] {
+            "StrawPotentials",
+            "StrawUtilizations",
+            "StrawConverterCapacities"});
+      this.valueLayerNamesListBox.Location = new System.Drawing.Point(3, 161);
+      this.valueLayerNamesListBox.Name = "valueLayerNamesListBox";
+      this.valueLayerNamesListBox.Size = new System.Drawing.Size(208, 420);
+      this.valueLayerNamesListBox.TabIndex = 22;
+      this.valueLayerNamesListBox.SelectedIndexChanged += new System.EventHandler(this.valueLayerNamesListBox_SelectedIndexChanged);
+      // 
+      // vectorLayerNamesListBox
+      // 
+      this.vectorLayerNamesListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.vectorLayerNamesListBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
+      this.vectorLayerNamesListBox.FormattingEnabled = true;
+      this.vectorLayerNamesListBox.HorizontalScrollbar = true;
+      this.vectorLayerNamesListBox.Location = new System.Drawing.Point(3, 21);
+      this.vectorLayerNamesListBox.Name = "vectorLayerNamesListBox";
+      this.vectorLayerNamesListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiSimple;
+      this.vectorLayerNamesListBox.Size = new System.Drawing.Size(208, 121);
+      this.vectorLayerNamesListBox.TabIndex = 23;
+      this.vectorLayerNamesListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.vectorLayerNamesListBox_DrawItem);
+      this.vectorLayerNamesListBox.SelectedIndexChanged += new System.EventHandler(this.vectorLayerNamesListBox_SelectedIndexChanged);
+      // 
+      // regionDescriptionLabel
+      // 
+      this.regionDescriptionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.regionDescriptionLabel.Location = new System.Drawing.Point(3, 601);
+      this.regionDescriptionLabel.Margin = new System.Windows.Forms.Padding(3);
+      this.regionDescriptionLabel.MaximumSize = new System.Drawing.Size(500, 13);
+      this.regionDescriptionLabel.Name = "regionDescriptionLabel";
+      this.regionDescriptionLabel.Size = new System.Drawing.Size(207, 13);
+      this.regionDescriptionLabel.TabIndex = 24;
+      this.regionDescriptionLabel.Text = "Vienna";
+      this.regionDescriptionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // regionNameLabel
+      // 
+      this.regionNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.regionNameLabel.Location = new System.Drawing.Point(3, 585);
+      this.regionNameLabel.MaximumSize = new System.Drawing.Size(500, 13);
+      this.regionNameLabel.Name = "regionNameLabel";
+      this.regionNameLabel.Size = new System.Drawing.Size(207, 13);
+      this.regionNameLabel.TabIndex = 25;
+      this.regionNameLabel.Text = "AT111";
+      this.regionNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // splitContainer2
+      // 
+      this.splitContainer2.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.splitContainer2.Location = new System.Drawing.Point(3, 3);
+      this.splitContainer2.Name = "splitContainer2";
+      // 
+      // splitContainer2.Panel1
+      // 
+      this.splitContainer2.Panel1.Controls.Add(this.mapBox);
+      // 
+      // splitContainer2.Panel2
+      // 
+      this.splitContainer2.Panel2.Controls.Add(this.regionDetailView);
+      this.splitContainer2.Panel2.Controls.Add(this.saveMapImageButton);
+      this.splitContainer2.Size = new System.Drawing.Size(870, 638);
+      this.splitContainer2.SplitterDistance = 567;
+      this.splitContainer2.TabIndex = 14;
+      // 
+      // regionDetailView
+      // 
+      this.regionDetailView.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.regionDetailView.Caption = "View";
+      this.regionDetailView.Content = null;
+      this.regionDetailView.Location = new System.Drawing.Point(3, 7);
+      this.regionDetailView.Name = "regionDetailView";
+      this.regionDetailView.ReadOnly = false;
+      this.regionDetailView.Size = new System.Drawing.Size(293, 599);
+      this.regionDetailView.TabIndex = 13;
+      this.regionDetailView.RegionLabelClicked += new System.EventHandler(this.solutionDetailView_RegionLabelClicked);
+      // 
+      // saveMapImageButton
+      // 
+      this.saveMapImageButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.saveMapImageButton.Location = new System.Drawing.Point(129, 612);
+      this.saveMapImageButton.Name = "saveMapImageButton";
+      this.saveMapImageButton.Size = new System.Drawing.Size(167, 23);
+      this.saveMapImageButton.TabIndex = 12;
+      this.saveMapImageButton.Text = "Save Map Image ...";
+      this.saveMapImageButton.UseVisualStyleBackColor = true;
+      this.saveMapImageButton.Click += new System.EventHandler(this.saveMapImageButton_Click);
+      // 
+      // tabPage2
+      // 
+      this.tabPage2.Controls.Add(this.bioBoostSolutionCostsView1);
+      this.tabPage2.Controls.Add(this.regionsTreeView);
+      this.tabPage2.Location = new System.Drawing.Point(4, 22);
+      this.tabPage2.Name = "tabPage2";
+      this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage2.Size = new System.Drawing.Size(1106, 656);
+      this.tabPage2.TabIndex = 1;
+      this.tabPage2.Text = "Costs";
+      this.tabPage2.UseVisualStyleBackColor = true;
+      // 
+      // bioBoostSolutionCostsView1
+      // 
+      this.bioBoostSolutionCostsView1.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.bioBoostSolutionCostsView1.Caption = "View";
+      this.bioBoostSolutionCostsView1.Content = null;
+      this.bioBoostSolutionCostsView1.Location = new System.Drawing.Point(174, 6);
+      this.bioBoostSolutionCostsView1.Name = "bioBoostSolutionCostsView1";
+      this.bioBoostSolutionCostsView1.ReadOnly = false;
+      this.bioBoostSolutionCostsView1.Size = new System.Drawing.Size(926, 644);
+      this.bioBoostSolutionCostsView1.TabIndex = 0;
+      // 
+      // regionsTreeView
+      // 
+      this.regionsTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left)));
+      this.regionsTreeView.Location = new System.Drawing.Point(3, 6);
+      this.regionsTreeView.Name = "regionsTreeView";
+      treeNode1.Name = "AT111";
+      treeNode1.Text = "AT111";
+      treeNode2.Name = "AT112";
+      treeNode2.Text = "AT112";
+      treeNode3.Name = "AT";
+      treeNode3.Text = "AT";
+      treeNode4.Name = "BE112";
+      treeNode4.Text = "BE112";
+      treeNode5.Name = "BE";
+      treeNode5.Text = "BE";
+      treeNode6.Name = "All Regions";
+      treeNode6.Text = "All Regions";
+      this.regionsTreeView.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
+            treeNode6});
+      this.regionsTreeView.Size = new System.Drawing.Size(165, 647);
+      this.regionsTreeView.TabIndex = 0;
+      this.regionsTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.regionsTreeView_AfterSelect);
+      // 
+      // tabPage3
+      // 
+      this.tabPage3.Controls.Add(this.openSolutionEditorButton);
+      this.tabPage3.Location = new System.Drawing.Point(4, 22);
+      this.tabPage3.Name = "tabPage3";
+      this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage3.Size = new System.Drawing.Size(1106, 656);
+      this.tabPage3.TabIndex = 2;
+      this.tabPage3.Text = "Edit / Optimize Solution";
+      this.tabPage3.UseVisualStyleBackColor = true;
+      // 
+      // openSolutionEditorButton
+      // 
+      this.openSolutionEditorButton.Location = new System.Drawing.Point(6, 6);
+      this.openSolutionEditorButton.Name = "openSolutionEditorButton";
+      this.openSolutionEditorButton.Size = new System.Drawing.Size(113, 23);
+      this.openSolutionEditorButton.TabIndex = 0;
+      this.openSolutionEditorButton.Text = "Open Editor View";
+      this.openSolutionEditorButton.UseVisualStyleBackColor = true;
+      this.openSolutionEditorButton.Click += new System.EventHandler(this.openSolutionEditorButton_Click);
+      // 
+      // saveFileDialog
+      // 
+      this.saveFileDialog.DefaultExt = "png";
+      this.saveFileDialog.Filter = "PNG files|*.png|All files|*.*";
+      this.saveFileDialog.RestoreDirectory = true;
+      // 
+      // tabPage4
+      // 
+      this.tabPage4.Controls.Add(this.summaryView);
+      this.tabPage4.Location = new System.Drawing.Point(4, 22);
+      this.tabPage4.Name = "tabPage4";
+      this.tabPage4.Size = new System.Drawing.Size(1106, 656);
+      this.tabPage4.TabIndex = 3;
+      this.tabPage4.Text = "Summary";
+      this.tabPage4.UseVisualStyleBackColor = true;
+      // 
+      // summaryView
+      // 
+      this.summaryView.Caption = "View";
+      this.summaryView.Content = null;
+      this.summaryView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.summaryView.Location = new System.Drawing.Point(0, 0);
+      this.summaryView.Name = "summaryView";
+      this.summaryView.ReadOnly = false;
+      this.summaryView.Size = new System.Drawing.Size(1106, 656);
+      this.summaryView.TabIndex = 0;
+      // 
+      // BioBoostCompoundSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl1);
+      this.Name = "BioBoostCompoundSolutionView";
+      this.Size = new System.Drawing.Size(1114, 682);
+      this.tabControl1.ResumeLayout(false);
+      this.tabPage1.ResumeLayout(false);
+      this.splitContainer1.Panel1.ResumeLayout(false);
+      this.splitContainer1.Panel1.PerformLayout();
+      this.splitContainer1.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+      this.splitContainer1.ResumeLayout(false);
+      this.splitContainer2.Panel1.ResumeLayout(false);
+      this.splitContainer2.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
+      this.splitContainer2.ResumeLayout(false);
+      this.tabPage2.ResumeLayout(false);
+      this.tabPage3.ResumeLayout(false);
+      this.tabPage4.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private SharpMap.Forms.MapBox mapBox;
+    private System.Windows.Forms.TabControl tabControl1;
+    private System.Windows.Forms.TabPage tabPage1;
+    private System.Windows.Forms.TabPage tabPage2;
+    private System.Windows.Forms.TreeView regionsTreeView;
+    private BioBoostSolutionCostsView bioBoostSolutionCostsView1;
+    private System.Windows.Forms.TabPage tabPage3;
+    private System.Windows.Forms.Button openSolutionEditorButton;
+    private System.Windows.Forms.Button saveMapImageButton;
+    private System.Windows.Forms.SaveFileDialog saveFileDialog;
+    private BioBoostRegionDetailView regionDetailView;
+    private System.Windows.Forms.SplitContainer splitContainer1;
+    private System.Windows.Forms.Label valueLayerValueLabel;
+    private System.Windows.Forms.ListBox valueLayerNamesListBox;
+    private System.Windows.Forms.ListBox vectorLayerNamesListBox;
+    private System.Windows.Forms.Label regionDescriptionLabel;
+    private System.Windows.Forms.Label regionNameLabel;
+    private System.Windows.Forms.SplitContainer splitContainer2;
+    private System.Windows.Forms.TabPage tabPage4;
+    private BioBoostSummaryView summaryView;
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.cs	(revision 13072)
@@ -0,0 +1,644 @@
+﻿using System.CodeDom.Compiler;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using GeoAPI.Geometries;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.BioBoost.Utils;
+using HeuristicLab.BioBoost.Views.MapViews;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using NetTopologySuite.Geometries;
+using SharpMap.Data;
+using SharpMap.Forms;
+using SharpMap.Layers;
+using SharpMap.Rendering.Decoration;
+using SharpMap.Rendering.Decoration.ScaleBar;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.Linq;
+using System.Threading;
+using System.Windows.Forms;
+using System.Windows.Forms.VisualStyles;
+using HeuristicLab.BioBoost.Evaluators;
+using HeuristicLab.PluginInfrastructure;
+using Point = System.Drawing.Point;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof(BioBoostCompoundSolution), IsDefaultView = true)]
+  public partial class BioBoostCompoundSolutionView : ItemView {
+
+    private readonly Dictionary<String, ILazyLayerGenerator> layerCache;
+    private readonly GradientLegend legend;
+    private readonly Disclaimer disclaimer;
+    private Thread mapUpdateThread;
+    private Thread costsUpdateThread;
+    private ManualResetEventSlim updateMap;
+    private ManualResetEventSlim updateCosts;
+
+    private SharpMap.Rendering.Thematics.ColorBlend vectorColorBlend =
+      new SharpMap.Rendering.Thematics.ColorBlend(new[] {
+        Color.FromArgb(0, 0, 255),
+        Color.FromArgb(128, 0, 128),
+        Color.FromArgb(255, 0, 0),
+      }, new[] { 0f, .5f, 1f });
+    private string currentRegion;
+    public const string AllRegionsName = "All";
+
+    public new BioBoostCompoundSolution Content {
+      get { return (BioBoostCompoundSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public BioBoostCompoundSolutionView() {
+      InitializeComponent();
+      layerCache = new Dictionary<string, ILazyLayerGenerator>();
+      mapBox.Map.Decorations.Add(new ScaleBar {
+        Anchor = MapDecorationAnchor.RightBottom,
+        BarColor1 = Color.White,
+        BarColor2 = Color.Black,
+        BarStyle = ScaleBarStyle.Meridian,
+        MapUnit = (int)Unit.Degree,
+        BarUnit = (int)Unit.Kilometer,
+      });
+      disclaimer = new Disclaimer {
+        Anchor = MapDecorationAnchor.RightTop,
+        Text = "ForestryResidues Utilization",
+        Enabled = true,
+        BackgroundColor = Color.FromArgb(128, 255, 255, 255),
+        ForeColor = Color.Black,
+        BorderColor = Color.Transparent,
+        Font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular)
+      };
+      legend = new GradientLegend {Size = new Size(300, 20)};
+      mapBox.Map.Decorations.Add(legend);
+      mapBox.Map.Decorations.Add(new NorthArrow());
+      mapBox.Map.Decorations.Add(disclaimer);
+        
+      updateMap = new ManualResetEventSlim(true);
+      mapUpdateThread = new Thread(UpdateMap);
+      mapUpdateThread.Start();
+      updateCosts = new ManualResetEventSlim(true);
+      costsUpdateThread = new Thread(UpdateCosts);
+      costsUpdateThread.Start();
+      currentRegion = AllRegionsName;
+    }
+
+
+    protected override void DeregisterContentEvents() {
+      Content.SolutionChanged -= SolutionChanged;
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.SolutionChanged += SolutionChanged;
+    }
+
+    #region Event Handlers (Content)
+
+    private void SolutionChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler<EventArgs>(SolutionChanged), sender, e);
+      } else {
+        UpgradeSolution();
+        InitializeLayers();
+        DiscoverLayerNames();
+        summaryView.Content = new RegionDetailData {RegionName = null, Solution = Content};
+        ShowSelectedLayers(false);
+        ShowCosts();
+      }
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        ClearAllLayerNames();
+        ClearCostsSummary();
+      } else {
+        UpgradeSolution();
+        InitializeLayers();
+        DiscoverLayerNames();
+        summaryView.Content = new RegionDetailData {RegionName = null, Solution = Content};
+        ShowSelectedLayers(true);
+        ShowCosts();
+      }
+    }
+
+    private bool upgradeInProgress = false;
+    private void UpgradeSolution() {
+      if (Content != null && !upgradeInProgress) {
+        upgradeInProgress = true;
+        Content.UpdateTo(new BioBoostCompoundSolution(
+          AggregateEvaluator.Evaluate(Content.ProblemDataReference, Content.DoubleValues, Content.IntValues),
+          Content.ProblemDataReference));
+        upgradeInProgress = false;
+      }
+    }
+
+    #region Main Logic
+    private void ResetZoom() {
+      if (mapBox.Map.Layers.Count > 0)
+        mapBox.Map.ZoomToExtents();
+      mapBox.ActiveTool = MapBox.Tools.Pan;
+      mapBox.Refresh();
+    }
+
+    private void DiscoverLayerNames() {
+      DiscoverValueLayers();
+      DiscoverVectorLayers();
+    }
+
+    private class ListBoxItem {
+      public Color Color;
+      public String Text;
+    }
+
+    private void DiscoverVectorLayers() {
+      var layerNames = vectorLayerNamesListBox.Items.Cast<ListBoxItem>().Select(l => l.Text).ToList();
+      if (layerNames.SequenceEqual(Content.IntValues.Keys)) return;
+      vectorLayerNamesListBox.BeginUpdate();
+      vectorLayerNamesListBox.Items.Clear();
+      int i = 0, n = Math.Max(1, Content.IntValues.Count - 1);
+      foreach (var values in Content.IntValues) {
+        var newItem = new ListBoxItem {
+          Color = vectorColorBlend.GetColor(1f * i++ / n),
+          Text = values.Key
+        };
+        vectorLayerNamesListBox.Items.Add(newItem);
+        if (layerNames.Any(name => name == values.Key) || layerNames.Count == 0)
+          vectorLayerNamesListBox.SelectedItems.Add(newItem);
+      }
+      vectorLayerNamesListBox.EndUpdate();
+    }
+
+    private void DiscoverValueLayers() {
+      var layerNames = AddRelativePotentials(Content.DoubleValues.Keys).ToList();
+      layerNames.Sort();
+      if (valueLayerNamesListBox.Items.Cast<string>().SequenceEqual(layerNames))
+        return;
+      valueLayerNamesListBox.BeginUpdate();
+      var selectedValueLayerName = (string)valueLayerNamesListBox.SelectedItem;
+      var firstFinalProduct = Content.ProblemDataReference.FinalProducts.FirstOrDefault();
+      if (selectedValueLayerName == null && firstFinalProduct != null)
+        selectedValueLayerName = LayerDescriptor.RelativeCostAtSource.NameWithPrefix(firstFinalProduct.Value);
+      valueLayerNamesListBox.Items.Clear();
+      foreach (var name in layerNames) {
+        var i = valueLayerNamesListBox.Items.Add(name);
+        if (name == selectedValueLayerName)
+          valueLayerNamesListBox.SelectedIndex = i;
+      }
+      if (valueLayerNamesListBox.SelectedIndex == -1)
+        valueLayerNamesListBox.SelectedIndex = 0;
+      valueLayerNamesListBox.EndUpdate();
+    }
+
+    private IEnumerable<string> AddRelativePotentials(IEnumerable<string> names) {
+      foreach (var name in names) {
+        if (LayerDescriptor.PotentialsFromProblemData.IsSuffixOf(name)) {
+          var formattedName = name.Replace(LayerDescriptor.PotentialsFromProblemData.FullName, " Potentials");
+          yield return formattedName;
+          yield return formattedName + " Relative";
+        } else {
+          yield return name;
+        }
+      }
+    }
+
+    private void ClearAllLayerNames() {
+      valueLayerNamesListBox.Items.Clear();
+      vectorLayerNamesListBox.Items.Clear();
+    }
+
+    private void ShowSelectedLayers(bool resetZoom) {
+      lock (updateMap) {
+        if (pendingUpdate != null) {
+          pendingUpdate.ResetZoom |= resetZoom;
+        } else {
+          pendingUpdate = new BackgroundArguments { ResetZoom = resetZoom };
+        }
+        updateMap.Set();
+      }
+    }
+
+    private void ShowCosts() {
+      updateCosts.Set();
+    }
+
+    private sealed class BackgroundArguments {
+      public bool ResetZoom;
+      public LazyValueLayerGenerator ValueLayerGenerator;
+      public List<LazyVectorLayerGenerator> VectorLayerGenerators;
+      public ILayer ValueLayer;
+      public List<ILayer> TransportLayers;
+    }
+
+    private BackgroundArguments pendingUpdate;
+    private bool runningUpdateMap = true;
+    private bool runningUpdateCosts = true;
+
+    private void UpdateMap() {
+      while (runningUpdateMap) {
+        BackgroundArguments currentUpdate = null;
+        // wait for a signal to update the map
+        while (!updateMap.Wait(2000)) {
+          if (!runningUpdateMap) return; // stop thread if requested
+        }
+        lock (updateMap) {
+          updateMap.Reset();
+          currentUpdate = pendingUpdate;
+          pendingUpdate = null;
+        }
+
+        // only do something if the map-tab is active
+        if (currentUpdate != null) {
+          DoShowSelectedLayers(currentUpdate);
+        }
+        Thread.Sleep(500);
+      }
+    }
+
+    private void UpdateCosts() {
+      while (runningUpdateCosts) {
+        // wait for signal to update the costs
+        while (!updateCosts.Wait(2000)) {
+          if (!runningUpdateCosts) return; // stop the thread if requested
+        }
+        updateCosts.Reset();
+
+        ClearCostsSummary();
+        PopulateRegionTree();
+        PopulateCostsSummary();
+
+        Thread.Sleep(500);
+      }
+    }
+
+    private void DoShowSelectedLayers(BackgroundArguments args) {
+      if (InvokeRequired) {
+        try {
+          var result = BeginInvoke(new Action<BackgroundArguments>(DoShowSelectedLayers), args);
+          result.AsyncWaitHandle.WaitOne();
+          EndInvoke(result);
+        } catch (ObjectDisposedException) { }
+      } else {
+        // only do something if the map-tab is active
+        if (tabControl1.SelectedTab != tabPage1) return;
+
+        GetConfigFromUI(args);
+        var generator = args.ValueLayerGenerator;
+        if (generator == null) return;
+        args.ValueLayer = generator.Layer; // this might take a while
+        args.TransportLayers = new List<ILayer>();
+        foreach (var g in args.VectorLayerGenerators) {
+          args.TransportLayers.Add(g.Layer); // TODO: cycle colors of vectors
+        }
+        UpdateUI(args);
+      }
+    }
+
+    private void GetConfigFromUI(BackgroundArguments args) {
+      var valueLayerName = (string)valueLayerNamesListBox.SelectedItem;
+      var vectorLayerNames = vectorLayerNamesListBox.SelectedItems.Cast<ListBoxItem>().Select(i => i.Text);
+      if (String.IsNullOrEmpty(valueLayerName)) return;
+      var generator = layerCache[valueLayerName] as LazyValueLayerGenerator;
+      if (generator == null) return;
+      args.ValueLayerGenerator = generator;
+      args.VectorLayerGenerators =
+        vectorLayerNames.Select(n => layerCache[n] as LazyVectorLayerGenerator).Where(g => g != null).ToList();
+
+    }
+
+    private void UpdateUI(BackgroundArguments args) {
+      if (IsDisposed || Disposing) return;
+      try {
+        var currentZoom = mapBox.Map.Zoom;
+        var currentCenter = mapBox.Map.Center;
+        mapBox.Map.Layers.Clear();
+        mapBox.Map.Layers.Add(args.ValueLayer);
+        foreach (var tl in args.TransportLayers)
+          mapBox.Map.Layers.Add(tl);
+        legend.MinValue = args.ValueLayerGenerator.ActualMinValue;
+        legend.MaxValue = args.ValueLayerGenerator.ActualMaxValue;
+        legend.Unit = args.ValueLayerGenerator.Unit;
+        legend.ColorBlend = new ColorBlend {
+          Colors = args.ValueLayerGenerator.ColorBlend.Colors,
+          Positions = args.ValueLayerGenerator.ColorBlend.Positions,
+        };
+        disclaimer.Text = args.ValueLayer.LayerName;
+        if (args.ResetZoom) {
+          ResetZoom();
+        } else {
+          mapBox.ActiveTool = MapBox.Tools.Pan;
+          mapBox.Map.Zoom = currentZoom;
+          mapBox.Map.Center = currentCenter;
+          mapBox.Refresh();
+        }
+      } catch (Exception x) {
+        MessageBox.Show(this, "Could not update UI, please try again:\n" + x);
+      }
+    }
+
+    private void InitializeLayers() {
+      lock (updateMap) {
+        layerCache.Clear();
+        var geom = Content.Geometry;
+        var locs = Content.LocationNames;
+        foreach (var kvp in Content.DoubleValues) {
+          var generator = new LazyValueLayerGenerator(geom, locs, kvp.Value, kvp.Key);
+          var name = kvp.Key;
+          if (kvp.Value.Min() > 0) generator.MinValue = 0;
+          if (kvp.Value.Max() < 0) generator.MaxValue = 0;
+          var layer = LayerDescriptor.GetLayer(name);
+          if (layer == LayerDescriptor.Utilizations || layer == LayerDescriptor.UtilizationsEffective) {
+            generator.MaxValue = 1;
+          } else if (layer == Representation.LayerDescriptor.PotentialsFromProblemData) {
+            generator.Unit = "t/a";
+            name = name.Replace(LayerDescriptor.PotentialsFromProblemData.FullName, " Potentials");
+            layerCache.Add(name + " Relative", new LazyValueLayerGenerator(geom, locs, kvp.Value, name + " Relative") {
+              MinValue = 0,
+              RealtiveToSize = true,
+              Unit = "t/ha/a"
+            });
+          } else {
+            if (layer != null)
+              generator.Unit = layer.Unit;
+          }
+          layerCache.Add(name, generator);
+        }
+        int i = 0, n = Math.Max(1, Content.IntValues.Count - 1);
+        foreach (var kvp in Content.IntValues) {
+          var name = kvp.Key;
+          var targets = kvp.Value;
+          var amounts = BioBoostCompoundSolution.FindAmountsTransportedFromSource(Content.DoubleValues, name);
+          if (amounts != null) {
+            for (int j = 0; j < amounts.Length; j++) {
+              if (amounts[j] <= 0) {
+                targets[j] = -1;
+              }
+            }
+          }
+          layerCache.Add(
+            name,
+            new LazyVectorLayerGenerator(geom, locs, targets,  amounts, vectorColorBlend.GetColor(1.0f * i / n), name) {
+              LineOffset = i * 2
+            });
+          i++;
+        }
+      }
+    }
+
+    private void ClearCostsSummary() {
+      if (InvokeRequired) {
+        try {
+          var result = BeginInvoke(new Action(ClearCostsSummary));
+          result.AsyncWaitHandle.WaitOne();
+          EndInvoke(result);
+        } catch (ObjectDisposedException) { }
+      } else {
+        if (IsDisposed || Disposing) return;
+        bioBoostSolutionCostsView1.Content = null;
+      }
+    }
+
+    private void PopulateCostsSummary() {
+      if (InvokeRequired) {
+        try {
+          var result = BeginInvoke(new Action(PopulateCostsSummary));
+          result.AsyncWaitHandle.WaitOne();
+          EndInvoke(result);
+        } catch (ObjectDisposedException) { }
+      } else {
+        if (IsDisposed || Disposing) return;
+        // only do something if the costs-tab is active
+        if (tabControl1.SelectedTab != tabPage2) return;
+
+        regionsTreeView.SelectedNode = regionsTreeView.Nodes.Find(currentRegion, true).FirstOrDefault();
+        regionsTreeView.Focus();
+        if (IsDisposed) return;
+        bioBoostSolutionCostsView1.Content = new RegionDetailData {
+          RegionName = currentRegion,
+          Solution = Content,
+        };
+      }
+    }
+
+    private void PopulateRegionTree() {
+      if (InvokeRequired) {
+        try {
+          var result = BeginInvoke(new Action(PopulateRegionTree));
+          result.AsyncWaitHandle.WaitOne();
+          EndInvoke(result);
+        } catch (ObjectDisposedException) { }
+      } else {
+        if (IsDisposed || Disposing) return;
+        regionsTreeView.Nodes.Clear();
+        if (Content == null) return;
+        regionsTreeView.Nodes.Add(AllRegionsName, AllRegionsName);
+        var allRegionsNodes = regionsTreeView.Nodes[AllRegionsName].Nodes;
+        foreach (var location in Content.LocationNames) {
+          var country = location.Substring(0, 2);
+          if (!allRegionsNodes.ContainsKey(country)) {
+            allRegionsNodes.Add(country, country);
+          }
+          allRegionsNodes[country].Nodes.Add(location, location);
+        }
+        regionsTreeView.HideSelection = false;
+        regionsTreeView.Nodes[AllRegionsName].Expand();
+      }
+    }
+
+    #endregion
+
+    public void SetFocus(string regionName) {
+      var row = Content.Geometry.Features.Rows.Cast<FeatureDataRow>().FirstOrDefault(r => (string)r["NUTS_ID"] == regionName);
+      if (row == null) return;
+      var coords = row.Geometry.Envelope.Buffer(1).Coordinates;
+      var env = new Envelope(coords.Min(c => c.X), coords.Max(c => c.X),
+                   coords.Min(c => c.Y), coords.Max(c => c.Y));
+      mapBox.Map.ZoomToBox(env);
+      mapBox.Refresh();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      vectorLayerNamesListBox.Enabled = Content != null;
+      valueLayerNamesListBox.Enabled = Content != null;
+      openSolutionEditorButton.Enabled = Content != null && !Locked;
+    }
+
+    #region Auxiliary Methods
+    private string GetRegionAtWorldPos(Coordinate loc) {
+      var ds = new FeatureDataSet();
+      Content.Geometry.ExecuteIntersectionQuery(new NetTopologySuite.Geometries.Point(loc), ds);
+      return (from FeatureDataRow row in ds.Tables[0]
+              select row["NUTS_ID"] as string).FirstOrDefault();
+    }
+
+    private string GetRegionDescription(string regionName) {
+      if (regionName != null && Content.Geometry.Features.Columns.Contains("name")) {
+        var row = Content.Geometry.Features.Rows.Cast<FeatureDataRow>().FirstOrDefault(r => (string)r["NUTS_ID"] == regionName);
+        if (row != null)
+          return row["name"].ToString();
+      }
+      return "";
+    }
+
+    private string GetCurrentValueLayerValue(string regionName) {
+      if (regionName == null) return "";
+      var layerName = valueLayerNamesListBox.SelectedItem as string;
+      if (layerName == null) return "";
+      var generator = layerCache[layerName] as LazyValueLayerGenerator;
+      if (generator == null) return "";
+      var mapping = generator.Mapping;
+      if (mapping == null) return "";
+      double value;
+      if (!mapping.TryGetValue(regionName, out value)) return "";
+      var v = Math.Abs(value);
+      //var format = v > 1000 ? "F0" : v > 100 ? "F1" : v > 10 ? "F2" : value < 0.01 ? "G" : "F3";
+      var format = v > 1000 ? "F0" : v > 100 ? "F1" : v > 10 ? "F2" : value < 0.01 ? "G" : "F3";
+      var info = (NumberFormatInfo)NumberFormatInfo.InvariantInfo.Clone();
+      info.NumberGroupSeparator = " ";
+      return string.Format("{0} {1}", value.ToString(format, info), generator.Unit);
+    }
+
+    #endregion
+
+    #region Event Handlers (child controls)
+    private void vectorLayerNamesListBox_SelectedIndexChanged(object sender, EventArgs e) {
+      ShowSelectedLayers(false);
+      vectorLayerNamesListBox.Invalidate();
+    }
+
+    private void valueLayerNamesListBox_SelectedIndexChanged(object sender, EventArgs e) {
+      ShowSelectedLayers(false);
+    }
+
+    private void mapBox_MouseMove(Coordinate worldPos, MouseEventArgs imagePos) {
+      var nuts_id = GetRegionAtWorldPos(worldPos);
+      var nuts_name = GetRegionDescription(nuts_id);
+      regionNameLabel.Text = nuts_id;
+      regionDescriptionLabel.Text = nuts_name;
+      valueLayerValueLabel.Text = GetCurrentValueLayerValue(nuts_id);
+      mapBox.Cursor = String.IsNullOrEmpty(nuts_id) ? Cursors.Default : Cursors.Hand;
+    }
+
+    private Point startPos = new Point(0, 0);
+    private void mapBox_MouseDown(Coordinate worldPos, MouseEventArgs imagePos) {
+      if (imagePos.Button == MouseButtons.Left) {
+        startPos = imagePos.Location;
+      }
+    }
+
+    private void mapBox_MouseUp(Coordinate worldPos, MouseEventArgs imagePos) {
+      if (imagePos.Button == MouseButtons.Left
+          && Util.Distance(imagePos.Location, startPos) < 4) {
+        currentRegion = GetRegionAtWorldPos(worldPos);
+        if (!String.IsNullOrEmpty(currentRegion)) {
+          regionDetailView.Content = new RegionDetailData {
+            RegionName = currentRegion,
+            Solution = Content,
+          };
+        }
+      }
+    }
+
+    private void solutionDetailView_RegionLabelClicked(object sender, EventArgs e) {
+      if (regionDetailView.Content != null)
+        SetFocus(regionDetailView.Content.RegionName);
+    }
+
+    private void vectorLayerNamesListBox_DrawItem(object sender, DrawItemEventArgs e) {
+      var item = vectorLayerNamesListBox.Items[e.Index];
+      var listBoxItem = item as ListBoxItem;
+      var foreColor = Color.Black;
+      if (listBoxItem != null) {
+        foreColor = listBoxItem.Color;
+      }
+      var backColor = vectorLayerNamesListBox.BackColor;
+      if (vectorLayerNamesListBox.SelectedItems.Contains(item)) {
+        backColor = foreColor;
+        foreColor = Color.White;
+      }
+      using (var backBrush = new SolidBrush(backColor)) {
+        e.Graphics.FillRectangle(backBrush, e.Bounds);
+      }
+      using (var foreBrush = new SolidBrush(foreColor)) {
+        e.Graphics.DrawString(
+          listBoxItem != null ? listBoxItem.Text : item.ToString(),
+          vectorLayerNamesListBox.Font, foreBrush, e.Bounds);
+      }
+    }
+    #endregion
+
+    private void tabControl1_Selected(object sender, TabControlEventArgs e) {
+      switch (e.TabPageIndex) {
+        case 0:
+          ShowSelectedLayers(false); // prepare for the map update
+          updateMap.Set(); // signal that the map should be updated once
+          break;
+        case 1:
+          updateCosts.Set(); // signal that the costs should be updated once
+          break;
+      }
+    }
+
+    private void regionsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
+      var labeltext = e.Node.Text.Split(' ');
+      if (labeltext.Length > 0)
+        currentRegion = labeltext[0];
+      if (e.Node.GetNodeCount(true) == 0) {
+        regionDetailView.Content = new RegionDetailData {
+          RegionName = currentRegion,
+          Solution = Content,
+        };
+      }
+
+      ClearCostsSummary();
+      PopulateCostsSummary();
+    }
+
+    private void openSolutionEditorButton_Click(object sender, EventArgs e) {
+      // clone solution and also clone problem-data separately (solution does not clone problem data itself)
+      var cloner = new Cloner();
+      var clonedSolution = cloner.Clone(Content);
+      var clonedProblemData = cloner.Clone(Content.ProblemDataReference);
+      clonedSolution.ProblemDataReference = clonedProblemData;
+
+      // create and open editor view for content
+      var vh = new ViewHost();
+      vh.Content = clonedSolution;
+      vh.ViewType = typeof (BioBoostCompoundSolutionEditor);
+      vh.Show();
+    }
+
+    public void SaveMapViewToPNG(string filename) {
+      var bitmap = new Bitmap(mapBox.Width, mapBox.Height);
+      mapBox.DrawToBitmap(bitmap, new Rectangle(0, 0, mapBox.Width, mapBox.Height));
+      bitmap.Save(filename);
+    }
+
+    private void saveMapImageButton_Click(object sender, EventArgs e) {
+      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
+        try {
+          Enabled = false;
+          SaveMapViewToPNG(saveFileDialog.FileName);
+        } catch (Exception x) {
+          ErrorHandling.ShowErrorDialog(this, x);
+        } finally {
+          Enabled = true;
+        }
+      }
+    }
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostCompoundSolutionView.resx	(revision 13072)
@@ -0,0 +1,129 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="valueLayersLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="vectorLayersLabel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="saveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.Designer.cs	(revision 13072)
@@ -0,0 +1,75 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostParetoSetView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.DataPoint dataPoint1 = new System.Windows.Forms.DataVisualization.Charting.DataPoint(-0.1D, 10000D);
+      this.paretoSetChart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+      ((System.ComponentModel.ISupportInitialize)(this.paretoSetChart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // paretoSetChart
+      // 
+      this.paretoSetChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.AxisX.IntervalAutoMode = System.Windows.Forms.DataVisualization.Charting.IntervalAutoMode.VariableCount;
+      chartArea1.AxisX.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Number;
+      chartArea1.AxisY.IntervalAutoMode = System.Windows.Forms.DataVisualization.Charting.IntervalAutoMode.VariableCount;
+      chartArea1.AxisY.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Number;
+      chartArea1.AxisY2.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Number;
+      chartArea1.Name = "ChartArea1";
+      this.paretoSetChart.ChartAreas.Add(chartArea1);
+      this.paretoSetChart.Location = new System.Drawing.Point(3, 3);
+      this.paretoSetChart.Name = "paretoSetChart";
+      series1.ChartArea = "ChartArea1";
+      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastPoint;
+      series1.Name = "Series1";
+      series1.Points.Add(dataPoint1);
+      series1.ToolTip = "#VALX, #VAL";
+      series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
+      series1.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
+      this.paretoSetChart.Series.Add(series1);
+      this.paretoSetChart.Size = new System.Drawing.Size(576, 353);
+      this.paretoSetChart.TabIndex = 0;
+      this.paretoSetChart.Text = "paretoSetChart";
+      this.paretoSetChart.DoubleClick += new System.EventHandler(this.paretoSetChart_DoubleClick);
+      this.paretoSetChart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.paretoSetChart_MouseDown);
+      // 
+      // BioBoostParetoSetView
+      // 
+      this.Controls.Add(this.paretoSetChart);
+      this.Name = "BioBoostParetoSetView";
+      this.Size = new System.Drawing.Size(582, 359);
+      ((System.ComponentModel.ISupportInitialize)(this.paretoSetChart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.DataVisualization.Charting.Chart paretoSetChart;
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.cs	(revision 13072)
@@ -0,0 +1,120 @@
+﻿using System;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.PluginInfrastructure;
+using NetTopologySuite.Noding;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof (ItemCollection<BioBoostCompoundSolution>), false)]
+  public partial class BioBoostParetoSetView : ItemView {
+
+    private Point mouseDownPos;
+
+    public new ItemCollection<BioBoostCompoundSolution> Content {
+      get { return (ItemCollection<BioBoostCompoundSolution>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public BioBoostParetoSetView() {
+      InitializeComponent();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ItemsAdded += UpdateChart;
+      Content.ItemsRemoved += UpdateChart;
+      Content.CollectionReset += UpdateChart;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.CollectionReset -= UpdateChart;
+      Content.ItemsRemoved -= UpdateChart;
+      Content.CollectionReset -= UpdateChart;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateChart(this, EventArgs.Empty);
+    }
+
+    protected virtual void UpdateChart(object sender, EventArgs args) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler(UpdateChart), sender, args);
+      } else {
+        try {
+          if (paretoSetChart.IsDisposed) return;
+          var points = paretoSetChart.Series[0].Points;
+          if (Content == null) {
+            points.Clear();
+            return;
+          }
+          var newPoints = Content.Where(solution => solution.Qualities.Length >= 2).Select(s => new { x = s.Qualities[0], y = s.Qualities[1], solution = s}).ToList();
+          if (newPoints.Count > 0) {
+            var chartArea = paretoSetChart.ChartAreas[0];
+            AdaptAxis(chartArea.AxisX, newPoints.Select(p => p.x), 1);
+            AdaptAxis(chartArea.AxisY, newPoints.Select(p => p.y), 1);
+            paretoSetChart.BeginInit();
+            points.Clear();
+            foreach (var point in newPoints) {
+              points.Add(new DataPoint(point.x, point.y) {
+                Tag = point.solution,
+              });
+            }
+            paretoSetChart.EndInit();
+          }
+        } catch (Exception x) {
+          ErrorHandling.ShowErrorDialog(x);
+        }
+      }
+    }
+
+    private void AdaptAxis(Axis axis, IEnumerable<double> values, int precision = 0, double overshot = 0.5, double margin = 0.25) {
+      var newMax = values.Max();
+      var newMin = values.Min();
+      var range = newMax - newMin;
+      newMax = newMax + range*margin;
+      newMin = newMin - range*margin;
+      if (range == 0) return;
+      var oldRange = axis.Maximum - axis.Minimum;
+      if (range*3 < oldRange) {
+        axis.Maximum = Math.Round(newMax+range*overshot, precision);
+        axis.Minimum = Math.Round(newMin-range*overshot , precision);
+      } else {
+        if (newMax > axis.Maximum) axis.Maximum = Math.Round(newMax+range*overshot, precision);
+        if (newMin < axis.Minimum) axis.Minimum = Math.Round(newMin-range*overshot, precision);
+      }
+    }
+
+    private void paretoSetChart_MouseDown(object sender, MouseEventArgs e) { mouseDownPos = e.Location; }
+    private void paretoSetChart_DoubleClick(object sender, EventArgs e) {
+      var pos = mouseDownPos;
+      var result = paretoSetChart.HitTest(pos.X, pos.Y, ChartElementType.DataPoint);
+      var point = result.Object as DataPoint;
+      if (point != null && point.Tag is IContent)
+        MainFormManager.MainForm.ShowContent((IContent)point.Tag);
+    }
+
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostParetoSetView.resx	(revision 13072)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.Designer.cs	(revision 13072)
@@ -0,0 +1,277 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostProblemDataView {
+    /// <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.dataPage = new System.Windows.Forms.TabPage();
+      this.splitRegionFactorsImportButton = new System.Windows.Forms.Button();
+      this.filterButton = new System.Windows.Forms.Button();
+      this.importDescriptorsButton = new System.Windows.Forms.Button();
+      this.checkButton = new System.Windows.Forms.Button();
+      this.importNeighborsButton = new System.Windows.Forms.Button();
+      this.loadShapeFileButton = new System.Windows.Forms.Button();
+      this.importDistancesButton = new System.Windows.Forms.Button();
+      this.importFeedstockButton = new System.Windows.Forms.Button();
+      this.parameterCollectionView = new HeuristicLab.Core.Views.ParameterCollectionView();
+      this.mapPage = new System.Windows.Forms.TabPage();
+      this.mapBox = new SharpMap.Forms.MapBox();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.dataPage.SuspendLayout();
+      this.mapPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Size = new System.Drawing.Size(604, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(669, 3);
+      // 
+      // tabControl
+      // 
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Controls.Add(this.dataPage);
+      this.tabControl.Controls.Add(this.mapPage);
+      this.tabControl.Location = new System.Drawing.Point(3, 26);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(682, 423);
+      this.tabControl.TabIndex = 3;
+      // 
+      // dataPage
+      // 
+      this.dataPage.Controls.Add(this.splitRegionFactorsImportButton);
+      this.dataPage.Controls.Add(this.filterButton);
+      this.dataPage.Controls.Add(this.importDescriptorsButton);
+      this.dataPage.Controls.Add(this.checkButton);
+      this.dataPage.Controls.Add(this.importNeighborsButton);
+      this.dataPage.Controls.Add(this.loadShapeFileButton);
+      this.dataPage.Controls.Add(this.importDistancesButton);
+      this.dataPage.Controls.Add(this.importFeedstockButton);
+      this.dataPage.Controls.Add(this.parameterCollectionView);
+      this.dataPage.Location = new System.Drawing.Point(4, 22);
+      this.dataPage.Name = "dataPage";
+      this.dataPage.Padding = new System.Windows.Forms.Padding(3);
+      this.dataPage.Size = new System.Drawing.Size(674, 397);
+      this.dataPage.TabIndex = 0;
+      this.dataPage.Text = "Data";
+      this.dataPage.UseVisualStyleBackColor = true;
+      // 
+      // splitRegionFactorsImportButton
+      // 
+      this.splitRegionFactorsImportButton.BackgroundImage = global::HeuristicLab.Problems.BioBoost.Views.Properties.Resources.Farm_Fresh_arrow_divide;
+      this.splitRegionFactorsImportButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+      this.splitRegionFactorsImportButton.Location = new System.Drawing.Point(166, 7);
+      this.splitRegionFactorsImportButton.Name = "splitRegionFactorsImportButton";
+      this.splitRegionFactorsImportButton.Size = new System.Drawing.Size(26, 26);
+      this.splitRegionFactorsImportButton.TabIndex = 10;
+      this.toolTip.SetToolTip(this.splitRegionFactorsImportButton, "import descriptors");
+      this.splitRegionFactorsImportButton.UseVisualStyleBackColor = true;
+      this.splitRegionFactorsImportButton.Click += new System.EventHandler(this.splitRegionFactorsImportButton_Click);
+      // 
+      // filterButton
+      // 
+      this.filterButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.filterButton.Location = new System.Drawing.Point(563, 7);
+      this.filterButton.Name = "filterButton";
+      this.filterButton.Size = new System.Drawing.Size(51, 23);
+      this.filterButton.TabIndex = 9;
+      this.filterButton.Text = "Filter...";
+      this.filterButton.UseVisualStyleBackColor = true;
+      this.filterButton.Click += new System.EventHandler(this.filterButton_Click);
+      // 
+      // importDescriptorsButton
+      // 
+      this.importDescriptorsButton.BackgroundImage = global::HeuristicLab.Problems.BioBoost.Views.Properties.Resources.FoamingBeakerCartoon;
+      this.importDescriptorsButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+      this.importDescriptorsButton.Location = new System.Drawing.Point(134, 6);
+      this.importDescriptorsButton.Name = "importDescriptorsButton";
+      this.importDescriptorsButton.Size = new System.Drawing.Size(26, 26);
+      this.importDescriptorsButton.TabIndex = 8;
+      this.toolTip.SetToolTip(this.importDescriptorsButton, "import descriptors");
+      this.importDescriptorsButton.UseVisualStyleBackColor = true;
+      this.importDescriptorsButton.Click += new System.EventHandler(this.importConversionsButton_Click);
+      // 
+      // checkButton
+      // 
+      this.checkButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.checkButton.Location = new System.Drawing.Point(620, 7);
+      this.checkButton.Name = "checkButton";
+      this.checkButton.Size = new System.Drawing.Size(48, 23);
+      this.checkButton.TabIndex = 7;
+      this.checkButton.Text = "Check";
+      this.checkButton.UseVisualStyleBackColor = true;
+      this.checkButton.Click += new System.EventHandler(this.checkButton_Click);
+      // 
+      // importNeighborsButton
+      // 
+      this.importNeighborsButton.BackgroundImage = global::HeuristicLab.Problems.BioBoost.Views.Properties.Resources.neighbors;
+      this.importNeighborsButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+      this.importNeighborsButton.Location = new System.Drawing.Point(102, 6);
+      this.importNeighborsButton.Name = "importNeighborsButton";
+      this.importNeighborsButton.Size = new System.Drawing.Size(26, 26);
+      this.importNeighborsButton.TabIndex = 6;
+      this.toolTip.SetToolTip(this.importNeighborsButton, "Import Neighbors");
+      this.importNeighborsButton.UseVisualStyleBackColor = true;
+      this.importNeighborsButton.Click += new System.EventHandler(this.importNeighborsButton_Click);
+      // 
+      // loadShapeFileButton
+      // 
+      this.loadShapeFileButton.BackgroundImage = global::HeuristicLab.Problems.BioBoost.Views.Properties.Resources.ShapefileIcon;
+      this.loadShapeFileButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+      this.loadShapeFileButton.Location = new System.Drawing.Point(6, 6);
+      this.loadShapeFileButton.Name = "loadShapeFileButton";
+      this.loadShapeFileButton.Size = new System.Drawing.Size(26, 26);
+      this.loadShapeFileButton.TabIndex = 4;
+      this.toolTip.SetToolTip(this.loadShapeFileButton, "Load Shapefile");
+      this.loadShapeFileButton.UseVisualStyleBackColor = true;
+      this.loadShapeFileButton.Click += new System.EventHandler(this.loadShapeFileButton_Click);
+      // 
+      // importDistancesButton
+      // 
+      this.importDistancesButton.BackgroundImage = global::HeuristicLab.Problems.BioBoost.Views.Properties.Resources.Transport;
+      this.importDistancesButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+      this.importDistancesButton.Location = new System.Drawing.Point(70, 6);
+      this.importDistancesButton.Name = "importDistancesButton";
+      this.importDistancesButton.Size = new System.Drawing.Size(26, 26);
+      this.importDistancesButton.TabIndex = 2;
+      this.toolTip.SetToolTip(this.importDistancesButton, "Import Distance Matrix");
+      this.importDistancesButton.UseVisualStyleBackColor = true;
+      this.importDistancesButton.Click += new System.EventHandler(this.importDistancesButton_Click);
+      // 
+      // importFeedstockButton
+      // 
+      this.importFeedstockButton.BackgroundImage = global::HeuristicLab.Problems.BioBoost.Views.Properties.Resources.WheatStraw;
+      this.importFeedstockButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+      this.importFeedstockButton.Location = new System.Drawing.Point(38, 6);
+      this.importFeedstockButton.Name = "importFeedstockButton";
+      this.importFeedstockButton.Size = new System.Drawing.Size(26, 26);
+      this.importFeedstockButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.importFeedstockButton, "Import Feedstock Potentials");
+      this.importFeedstockButton.UseVisualStyleBackColor = true;
+      this.importFeedstockButton.Click += new System.EventHandler(this.importFeedstockButton_Click);
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.AllowEditingOfHiddenParameters = true;
+      this.parameterCollectionView.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.parameterCollectionView.Caption = "ParameterCollection View";
+      this.parameterCollectionView.Content = null;
+      this.parameterCollectionView.Location = new System.Drawing.Point(6, 38);
+      this.parameterCollectionView.Name = "parameterCollectionView";
+      this.parameterCollectionView.ReadOnly = false;
+      this.parameterCollectionView.ShowDetails = true;
+      this.parameterCollectionView.Size = new System.Drawing.Size(662, 353);
+      this.parameterCollectionView.TabIndex = 0;
+      // 
+      // mapPage
+      // 
+      this.mapPage.Controls.Add(this.mapBox);
+      this.mapPage.Location = new System.Drawing.Point(4, 22);
+      this.mapPage.Name = "mapPage";
+      this.mapPage.Padding = new System.Windows.Forms.Padding(3);
+      this.mapPage.Size = new System.Drawing.Size(674, 397);
+      this.mapPage.TabIndex = 1;
+      this.mapPage.Text = "Map";
+      this.mapPage.UseVisualStyleBackColor = true;
+      // 
+      // mapBox
+      // 
+      this.mapBox.ActiveTool = SharpMap.Forms.MapBox.Tools.Pan;
+      this.mapBox.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.mapBox.Cursor = System.Windows.Forms.Cursors.Hand;
+      this.mapBox.FineZoomFactor = 10D;
+      this.mapBox.Location = new System.Drawing.Point(6, 6);
+      this.mapBox.MapQueryMode = SharpMap.Forms.MapBox.MapQueryType.LayerByIndex;
+      this.mapBox.Name = "mapBox";
+      this.mapBox.PanOnClick = false;
+      this.mapBox.QueryGrowFactor = 5F;
+      this.mapBox.QueryLayerIndex = 0;
+      this.mapBox.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(210)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
+      this.mapBox.SelectionForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
+      this.mapBox.ShowProgressUpdate = false;
+      this.mapBox.Size = new System.Drawing.Size(662, 385);
+      this.mapBox.TabIndex = 0;
+      this.mapBox.TabStop = false;
+      this.mapBox.TakeFocusOnHover = true;
+      this.mapBox.Text = "mapBox";
+      this.mapBox.WheelZoomMagnitude = -2D;
+      this.mapBox.MouseClick += new System.Windows.Forms.MouseEventHandler(this.mapBox_MouseClick);
+      // 
+      // openFileDialog
+      // 
+      this.openFileDialog.DefaultExt = "*.csv";
+      this.openFileDialog.Filter = "All Files|*.*";
+      this.openFileDialog.Title = "Import File";
+      // 
+      // BioBoostProblemDataView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl);
+      this.Name = "BioBoostProblemDataView";
+      this.Size = new System.Drawing.Size(688, 452);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.dataPage.ResumeLayout(false);
+      this.mapPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage dataPage;
+    private System.Windows.Forms.TabPage mapPage;
+    private SharpMap.Forms.MapBox mapBox;
+    private Core.Views.ParameterCollectionView parameterCollectionView;
+    private System.Windows.Forms.Button importDistancesButton;
+    private System.Windows.Forms.Button importFeedstockButton;
+    private System.Windows.Forms.OpenFileDialog openFileDialog;
+    private System.Windows.Forms.Button loadShapeFileButton;
+    private System.Windows.Forms.Button importNeighborsButton;
+    private System.Windows.Forms.Button checkButton;
+    private System.Windows.Forms.Button importDescriptorsButton;
+    private System.Windows.Forms.Button filterButton;
+    private System.Windows.Forms.Button splitRegionFactorsImportButton;
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.cs	(revision 13072)
@@ -0,0 +1,295 @@
+﻿using GeoAPI.Geometries;
+using HeuristicLab.BioBoost.Persistence;
+using HeuristicLab.BioBoost.ProblemDescription;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Persistence.Default.Xml;
+using SharpMap.Data;
+using SharpMap.Data.Providers;
+using SharpMap.Forms;
+using SharpMap.Layers;
+using SharpMap.Rendering.Thematics;
+using SharpMap.Styles;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Windows.Forms;
+using ColorBlend = SharpMap.Rendering.Thematics.ColorBlend;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof(BioBoostProblemData), IsDefaultView = true)]
+  public partial class BioBoostProblemDataView : NamedItemView {
+
+    public new BioBoostProblemData Content {
+      get { return (BioBoostProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private VectorLayer regions;
+    private FilterDialog filterDialog;
+
+    public BioBoostProblemDataView() {
+      InitializeComponent();
+      filterDialog = new FilterDialog();
+    }
+
+    private GeometryFeatureProvider gfp2;
+    private void PrepareMap(object sender, DoWorkEventArgs e) {
+      var gfp = ShapeFileLoader.LoadShapeFile("C:\\Users\\P40031\\SkyDrive\\NUTS3\\NUTS3_regions_2010_WGS84.shp"); // TODO!
+      var ms = new MemoryStream();
+      XmlGenerator.Serialize(gfp, ms);
+      gfp2 = XmlParser.Deserialize<GeometryFeatureProvider>(new MemoryStream(ms.ToArray()));
+    }
+
+    private void ShowMap(object sender, RunWorkerCompletedEventArgs e) {
+      var outline = new Pen(Color.FromArgb(128, Color.White), 0.5f);
+      var small = new VectorStyle { Fill = Brushes.Blue, EnableOutline = true, Outline = outline };
+      var large = new VectorStyle { Fill = Brushes.Red, EnableOutline = true, Outline = outline };
+      regions = new VectorLayer("NUTS3 Regions") {
+        DataSource = gfp2,
+        Theme =
+          new GradientTheme("Shape_Area", 0, 5, small, large) { FillColorBlend = ColorBlend.Rainbow5 },
+      };
+
+      // add labels
+      var l = new LabelLayer("NUTS3 Labels") {
+        DataSource = gfp2,
+        LabelColumn = "NUTS_ID",
+        PriorityColumn = "Shape_Area",
+      };
+
+      // add geometries
+      var geometries = new Collection<IGeometry>();
+      GeoAPI.GeometryServiceProvider.Instance = new NetTopologySuite.NtsGeometryServices();
+      var f = GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory(4326);
+      regions.DataSource.Open();
+      var rows = regions.DataSource.GetObjectIDsInView(regions.Envelope);
+      foreach (var row in rows) {
+        var source = regions.DataSource.GetFeature(row).Geometry.Centroid;
+        var ds = new FeatureDataSet();
+        regions.DataSource.ExecuteIntersectionQuery(source.Buffer(0.1), ds);
+        var neighbors = ds.Tables[0].Rows;
+        if (neighbors.Count > 0) {
+          var ls = f.CreateLineString(new[] {
+            source.Coordinate,
+            ((FeatureDataRow) neighbors[rng.Next(neighbors.Count)]).
+                                        Geometry.Centroid.
+                                        Coordinate,
+          });
+          geometries.Add(ls);
+        }
+      }
+      regions.DataSource.Close();
+      var v = new VectorLayer("Vectors") {
+        DataSource = new GeometryProvider(geometries),
+      };
+      v.Style.Line.SetLineCap(LineCap.NoAnchor, LineCap.ArrowAnchor, DashCap.Flat);
+
+      // add layers
+      mapBox.Map.Layers.Add(regions);
+      mapBox.Map.Layers.Add(l);
+      mapBox.Map.Layers.Add(v);
+
+      // configure map
+      mapBox.Map.ZoomToExtents();
+      mapBox.Refresh();
+      mapBox.ActiveTool = MapBox.Tools.Pan;
+      tabControl.SelectedTab = mapPage;
+    }
+
+    private readonly Dictionary<string, VectorStyle> styles = new Dictionary<string, VectorStyle>();
+    private readonly Random rng = new Random();
+    private VectorStyle GetRandomStyle(FeatureDataRow row) {
+      var name = row["NUTS_ID"].ToString();
+      VectorStyle style;
+      if (!styles.TryGetValue(name, out style)) {
+        style = new VectorStyle {
+          Fill = new SolidBrush(Color.FromArgb(rng.Next(256), rng.Next(256), rng.Next(256)))
+        };
+        styles[name] = style;
+      }
+      return style;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.GeometryChanged -= GeometryChanged;
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.GeometryChanged += GeometryChanged;
+    }
+
+
+    #region Event Handlers (Content)
+    private void GeometryChanged(object sender, EventArgs eventArgs) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler<EventArgs>(GeometryChanged), new object[] { sender, eventArgs });
+      } else {
+        UpdateMap();
+      }
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        parameterCollectionView.Content = null;
+      } else {
+        parameterCollectionView.Content = Content.Parameters;
+      }
+      UpdateMap();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      parameterCollectionView.Enabled = Content != null;
+      loadShapeFileButton.Enabled = Content != null;
+      importFeedstockButton.Enabled = Content != null;
+      importDistancesButton.Enabled = Content != null;
+    }
+
+    private void UpdateMap() {
+      mapBox.Map.Layers.Clear();
+      mapBox.ShowProgressUpdate = false;
+      if (Content == null || Content.Geometry == null) return;
+      mapBox.ShowProgressUpdate = true;
+      var outline = new Pen(Color.FromArgb(128, Color.White), 0.5f);
+      var small = new VectorStyle { Fill = Brushes.Blue, EnableOutline = true, Outline = outline };
+      var large = new VectorStyle { Fill = Brushes.Red, EnableOutline = true, Outline = outline };
+      mapBox.Map.Layers.Add(new VectorLayer("Regions", Content.Geometry) {
+        //Theme = new GradientTheme("Shape_Area", 0, 5, small, large) {
+        //FillColorBlend = ColorBlend.Rainbow5,
+        //},
+      });
+      mapBox.Map.ZoomToExtents();
+      mapBox.Refresh();
+      mapBox.ActiveTool = MapBox.Tools.Pan;
+    }
+
+    #region Event Handlers (child controls)
+    private void mapBox_MouseClick(object sender, MouseEventArgs e) {
+      if (e.Button == MouseButtons.Right) {
+        var c = mapBox.Map.ImageToWorld(e.Location);
+        var f = GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory(4326);
+        var ds = new FeatureDataSet();
+        regions.ExecuteIntersectionQuery(f.CreatePoint(c), ds);
+        if (ds.Tables[0].Rows.Count > 0) {
+          var text = ds.Tables[0].Rows[0]["NUTS_ID"].ToString();
+          toolTip.SetToolTip(mapBox, text);
+        }
+      }
+    }
+
+    private void importFeedstockButton_Click(object sender, EventArgs e) {
+      openFileDialog.Filter = "Comma Separted Value|*.csv|All Files|*.*";
+      if (openFileDialog.ShowDialog() == DialogResult.OK) {
+        try {
+          Enabled = false;
+          Content.LoadFeedstockPotentials(openFileDialog.FileName);
+        } catch (Exception x) {
+          PluginInfrastructure.ErrorHandling.ShowErrorDialog(this, x);
+        } finally {
+          Enabled = true;
+        }
+      }
+    }
+
+    private void loadShapeFileButton_Click(object sender, EventArgs e) {
+      openFileDialog.Filter = "ESRI Shape Files|*.shp|All Files|*.*";
+      if (openFileDialog.ShowDialog() == DialogResult.OK) {
+        try {
+          Enabled = false;
+          Content.LoadShapeFile(openFileDialog.FileName);
+          tabControl.SelectedTab = mapPage;
+        } catch (Exception x) {
+          PluginInfrastructure.ErrorHandling.ShowErrorDialog(this, x);
+        } finally {
+          Enabled = true;
+        }
+      }
+    }
+
+    private void importDistancesButton_Click(object sender, EventArgs e) {
+      openFileDialog.Filter = "Comma Serparted Value|*.csv|All Files|*.*";
+      if (openFileDialog.ShowDialog() == DialogResult.OK) {
+        try {
+          Enabled = false;
+          Content.LoadDistanceMatrix(openFileDialog.FileName);
+        } catch (Exception x) {
+          PluginInfrastructure.ErrorHandling.ShowErrorDialog(this, x);
+        } finally {
+          Enabled = true;
+        }
+      }
+    }
+
+    private void importNeighborsButton_Click(object sender, EventArgs e) {
+      openFileDialog.Filter = "Comma Separated Value|*.csv|All Files|*.*";
+      if (openFileDialog.ShowDialog() == DialogResult.OK) {
+        try {
+          Enabled = false;
+          Content.LoadNeighbors(openFileDialog.FileName);
+        } catch (Exception x) {
+          PluginInfrastructure.ErrorHandling.ShowErrorDialog(this, x);
+        } finally {
+          Enabled = true;
+        }
+      }
+    }
+
+    private void checkButton_Click(object sender, EventArgs e) {
+      var warnings = Content.CheckGeoData();
+      if (!string.IsNullOrEmpty(warnings))
+        MessageBox.Show(warnings, "Warnings", MessageBoxButtons.OK);
+    }
+
+    private void importConversionsButton_Click(object sender, EventArgs e) {
+      openFileDialog.Filter = "YAML Files|*.yaml|All Files|*.*";
+      if (openFileDialog.ShowDialog() == DialogResult.OK) {
+        try {
+          Enabled = false;
+          Content.LoadDescriptors(openFileDialog.FileName);
+        } catch (Exception x) {
+          PluginInfrastructure.ErrorHandling.ShowErrorDialog(this, x);
+        } finally {
+          Enabled = true;
+        }
+      }
+
+    }
+
+    private void splitRegionFactorsImportButton_Click(object sender, EventArgs e) {
+      openFileDialog.Filter = "CSV Files|*.csv|All Files|*.*";
+      if (openFileDialog.ShowDialog() == DialogResult.OK) {
+        try {
+          Enabled = false;
+          Content.LoadSplitRegionDistanceFactors(openFileDialog.FileName);
+        } catch (Exception x) {
+          PluginInfrastructure.ErrorHandling.ShowErrorDialog(this, x);
+        } finally {
+          Enabled = true;
+        }
+      }
+    }
+
+    private void filterButton_Click(object sender, EventArgs e) {
+      if (filterDialog.ShowDialog() == DialogResult.OK) {
+        if (filterDialog.Keep) {
+          Content.KeepRegions(filterDialog.Regex);
+        } else {
+          Content.RemoveRegions(filterDialog.Regex);
+        }
+      }
+    }
+
+    #endregion
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostProblemDataView.resx	(revision 13072)
@@ -0,0 +1,132 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>140, 17</value>
+  </metadata>
+  <metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>230, 17</value>
+  </metadata>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.Designer.cs	(revision 13072)
@@ -0,0 +1,136 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostRegionDetailView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.GroupBox plantsGroupBox;
+      this.dataGridView = new System.Windows.Forms.DataGridView();
+      this.NameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      this.ValueColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      this.regionNameLabel = new System.Windows.Forms.LinkLabel();
+      this.regionDescriptionLabel = new System.Windows.Forms.Label();
+      plantsGroupBox = new System.Windows.Forms.GroupBox();
+      plantsGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // plantsGroupBox
+      // 
+      plantsGroupBox.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)));
+      plantsGroupBox.Controls.Add(this.dataGridView);
+      plantsGroupBox.Location = new System.Drawing.Point(3, 30);
+      plantsGroupBox.Name = "plantsGroupBox";
+      plantsGroupBox.Size = new System.Drawing.Size(286, 536);
+      plantsGroupBox.TabIndex = 4;
+      plantsGroupBox.TabStop = false;
+      plantsGroupBox.Text = "Regional Values";
+      // 
+      // dataGridView
+      // 
+      this.dataGridView.AllowUserToAddRows = false;
+      this.dataGridView.AllowUserToDeleteRows = false;
+      this.dataGridView.AllowUserToOrderColumns = true;
+      this.dataGridView.AllowUserToResizeRows = false;
+      this.dataGridView.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.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+            this.NameColumn,
+            this.ValueColumn});
+      this.dataGridView.Location = new System.Drawing.Point(7, 20);
+      this.dataGridView.Name = "dataGridView";
+      this.dataGridView.ReadOnly = true;
+      this.dataGridView.RowHeadersVisible = false;
+      this.dataGridView.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
+      this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
+      this.dataGridView.ShowEditingIcon = false;
+      this.dataGridView.Size = new System.Drawing.Size(273, 510);
+      this.dataGridView.TabIndex = 0;
+      // 
+      // NameColumn
+      // 
+      this.NameColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
+      this.NameColumn.HeaderText = "Name";
+      this.NameColumn.Name = "NameColumn";
+      this.NameColumn.ReadOnly = true;
+      this.NameColumn.Width = 60;
+      // 
+      // ValueColumn
+      // 
+      this.ValueColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
+      this.ValueColumn.HeaderText = "Value";
+      this.ValueColumn.Name = "ValueColumn";
+      this.ValueColumn.ReadOnly = true;
+      this.ValueColumn.Width = 59;
+      // 
+      // regionNameLabel
+      // 
+      this.regionNameLabel.ActiveLinkColor = System.Drawing.Color.Red;
+      this.regionNameLabel.Dock = System.Windows.Forms.DockStyle.Top;
+      this.regionNameLabel.Location = new System.Drawing.Point(0, 0);
+      this.regionNameLabel.Name = "regionNameLabel";
+      this.regionNameLabel.Size = new System.Drawing.Size(292, 14);
+      this.regionNameLabel.TabIndex = 0;
+      this.regionNameLabel.TabStop = true;
+      this.regionNameLabel.Text = "AT111";
+      this.regionNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      this.regionNameLabel.Click += new System.EventHandler(this.regionNameLabel_Click);
+      // 
+      // regionDescriptionLabel
+      // 
+      this.regionDescriptionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.regionDescriptionLabel.Location = new System.Drawing.Point(0, 14);
+      this.regionDescriptionLabel.MaximumSize = new System.Drawing.Size(500, 13);
+      this.regionDescriptionLabel.Name = "regionDescriptionLabel";
+      this.regionDescriptionLabel.Size = new System.Drawing.Size(292, 13);
+      this.regionDescriptionLabel.TabIndex = 8;
+      this.regionDescriptionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // BioBoostRegionDetailView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(plantsGroupBox);
+      this.Controls.Add(this.regionDescriptionLabel);
+      this.Controls.Add(this.regionNameLabel);
+      this.Name = "BioBoostRegionDetailView";
+      this.Size = new System.Drawing.Size(292, 569);
+      plantsGroupBox.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.LinkLabel regionNameLabel;
+    private System.Windows.Forms.Label regionDescriptionLabel;
+    private System.Windows.Forms.DataGridView dataGridView;
+    private System.Windows.Forms.DataGridViewTextBoxColumn NameColumn;
+    private System.Windows.Forms.DataGridViewTextBoxColumn ValueColumn;
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.cs	(revision 13072)
@@ -0,0 +1,90 @@
+﻿using System.Globalization;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using SharpMap.Data;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof(RegionDetailData), IsDefaultView = true)]
+  public partial class BioBoostRegionDetailView : ItemView {
+
+    public new RegionDetailData Content {
+      get { return (RegionDetailData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public BioBoostRegionDetailView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      dataGridView.Enabled = Content != null;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        Clear();
+      } else {
+        Clear();
+        Populate(Content.Solution, Content.RegionName);
+      }
+    }
+
+    public event EventHandler RegionLabelClicked;
+
+    protected void OnRegionLabelClicked() {
+      EventHandler h = RegionLabelClicked;
+      if (h != null)
+        h.Invoke(this, EventArgs.Empty);
+    }
+
+    private void Populate(BioBoostCompoundSolution solution, string regionName) {
+      regionNameLabel.Text = regionName; regionDescriptionLabel.Text = GetRegionDescription(regionName);
+      var locidx = solution.LocationNames.IndexOfFirst(s => s == regionName);
+      if (locidx < 0) return;
+      dataGridView.Rows.Clear();
+      foreach (var array in solution.DoubleValues) {
+        dataGridView.Rows.Add(array.Key, array.Value[locidx]);
+      }
+      dataGridView.Sort(NameColumn, ListSortDirection.Ascending);
+    }
+
+    private void Clear() {
+      regionNameLabel.Text = "";
+      regionDescriptionLabel.Text = "";
+      dataGridView.Rows.Clear();
+    }
+
+    private string GetRegionDescription(string regionName) {
+      if (regionName != null && Content.Solution.Geometry.Features.Columns.Contains("name")) {
+        var row = Content.Solution.Geometry.Features.Rows.Cast<FeatureDataRow>().FirstOrDefault(r => (string)r["NUTS_ID"] == regionName);
+        if (row != null)
+          return row["name"].ToString();
+      }
+      return "";
+    }
+
+    private void regionNameLabel_Click(object sender, EventArgs e) {
+      OnRegionLabelClicked();
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostRegionDetailView.resx	(revision 13072)
@@ -0,0 +1,129 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="plantsGroupBox.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+  <metadata name="NameColumn.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <metadata name="ValueColumn.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.Designer.cs	(revision 13072)
@@ -0,0 +1,137 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostSolutionCostsView {
+    /// <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.costsGroupBox = new System.Windows.Forms.GroupBox();
+      this.costsTextBox1 = new System.Windows.Forms.TextBox();
+      this.costsTextBox1Label = new System.Windows.Forms.Label();
+      this.costsDataGridView = new System.Windows.Forms.DataGridView();
+      this.costsColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      this.costsColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      this.costsGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.costsDataGridView)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // costsGroupBox
+      // 
+      this.costsGroupBox.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.costsGroupBox.Controls.Add(this.costsTextBox1);
+      this.costsGroupBox.Controls.Add(this.costsTextBox1Label);
+      this.costsGroupBox.Controls.Add(this.costsDataGridView);
+      this.costsGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.costsGroupBox.Name = "costsGroupBox";
+      this.costsGroupBox.Size = new System.Drawing.Size(349, 417);
+      this.costsGroupBox.TabIndex = 3;
+      this.costsGroupBox.TabStop = false;
+      this.costsGroupBox.Text = "Costs Summary";
+      // 
+      // costsTextBox1
+      // 
+      this.costsTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.costsTextBox1.BackColor = System.Drawing.SystemColors.Window;
+      this.costsTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
+      this.costsTextBox1.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.costsTextBox1.Location = new System.Drawing.Point(209, 399);
+      this.costsTextBox1.Name = "costsTextBox1";
+      this.costsTextBox1.ReadOnly = true;
+      this.costsTextBox1.Size = new System.Drawing.Size(134, 11);
+      this.costsTextBox1.TabIndex = 4;
+      this.costsTextBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
+      // 
+      // costsTextBox1Label
+      // 
+      this.costsTextBox1Label.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.costsTextBox1Label.AutoSize = true;
+      this.costsTextBox1Label.Location = new System.Drawing.Point(120, 397);
+      this.costsTextBox1Label.Name = "costsTextBox1Label";
+      this.costsTextBox1Label.Size = new System.Drawing.Size(89, 13);
+      this.costsTextBox1Label.TabIndex = 3;
+      this.costsTextBox1Label.Text = "Total Costs (€/a):";
+      // 
+      // costsDataGridView
+      // 
+      this.costsDataGridView.AllowUserToAddRows = false;
+      this.costsDataGridView.AllowUserToDeleteRows = false;
+      this.costsDataGridView.AllowUserToResizeRows = false;
+      this.costsDataGridView.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.costsDataGridView.BackgroundColor = System.Drawing.SystemColors.Window;
+      this.costsDataGridView.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+      this.costsDataGridView.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;
+      this.costsDataGridView.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;
+      this.costsDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.costsDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+            this.costsColumn1,
+            this.costsColumn2});
+      this.costsDataGridView.Location = new System.Drawing.Point(6, 19);
+      this.costsDataGridView.Name = "costsDataGridView";
+      this.costsDataGridView.ReadOnly = true;
+      this.costsDataGridView.RowHeadersVisible = false;
+      this.costsDataGridView.RowTemplate.Height = 16;
+      this.costsDataGridView.Size = new System.Drawing.Size(337, 374);
+      this.costsDataGridView.TabIndex = 0;
+      // 
+      // costsColumn1
+      // 
+      this.costsColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
+      this.costsColumn1.HeaderText = "Item";
+      this.costsColumn1.Name = "costsColumn1";
+      this.costsColumn1.ReadOnly = true;
+      // 
+      // costsColumn2
+      // 
+      this.costsColumn2.HeaderText = "€/a";
+      this.costsColumn2.MinimumWidth = 50;
+      this.costsColumn2.Name = "costsColumn2";
+      this.costsColumn2.ReadOnly = true;
+      this.costsColumn2.Width = 120;
+      // 
+      // BioBoostSolutionCostsView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.costsGroupBox);
+      this.Name = "BioBoostSolutionCostsView";
+      this.Size = new System.Drawing.Size(349, 417);
+      this.costsGroupBox.ResumeLayout(false);
+      this.costsGroupBox.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.costsDataGridView)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox costsGroupBox;
+    private System.Windows.Forms.DataGridView costsDataGridView;
+    private System.Windows.Forms.DataGridViewTextBoxColumn costsColumn1;
+    private System.Windows.Forms.DataGridViewTextBoxColumn costsColumn2;
+    private System.Windows.Forms.TextBox costsTextBox1;
+    private System.Windows.Forms.Label costsTextBox1Label;
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.cs	(revision 13072)
@@ -0,0 +1,175 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Globalization;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof(RegionDetailData), IsDefaultView = false)]
+  public partial class BioBoostSolutionCostsView : ItemView {
+
+    public new RegionDetailData Content {
+      get { return (RegionDetailData)base.Content; }
+      set { base.Content = value; }
+    }
+    
+    public BioBoostSolutionCostsView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        Clear();
+      } else {
+        Clear();
+        Populate(Content.Solution, Content.RegionName);
+      }
+    }
+
+    private Dictionary<string, double> costs;
+    private Dictionary<String, double> values; 
+    private Dictionary<string, List<string>> strings;
+
+    private void AddCost(string name, double value) {
+      // ReSharper disable once CompareOfFloatsByEqualityOperator
+      if (value == 0) return;
+      double oldValue = 0;
+      costs.TryGetValue(name, out oldValue);
+      costs[name] = oldValue + value;
+    }
+
+    private void AddSummableValue(string name, double value) {
+      // ReSharper disable once CompareOfFloatsByEqualityOperator
+      if (value == 0) return;
+      double oldValue = 0;
+      values.TryGetValue(name, out oldValue);
+      values[name] = oldValue + value;
+    }
+
+    private void AddString(string name, string value) {
+      if (string.IsNullOrEmpty(value) || value == "0") return;
+      List<String> oldValues;
+      if (!strings.TryGetValue(name, out oldValues)) {
+        oldValues = new List<string>();
+        strings[name] = oldValues;
+      }
+      if (oldValues.Count < 2) {
+        oldValues.Add(value);
+      }
+    }
+    
+
+    private void AddSupplierCosts(string name, DoubleArray values, List<int> supplierIndices) {
+      if (values == null) return;
+      double sum = 0;
+      foreach (var supplierIdx in supplierIndices) {
+        sum += values[supplierIdx];
+      }
+      AddCost(name + " Sum", sum);
+      if (supplierIndices.Count > 1)
+        AddString(name + " Avg", (sum/supplierIndices.Count).ToString(CultureInfo.InvariantCulture));
+    }
+
+    private void AddSupplierValues(string name, DoubleArray values, List<int> supplierIndices) {
+      if (values == null) return;
+      double sum = 0;
+      foreach (var supplierIdx in supplierIndices) {
+        sum += values[supplierIdx];
+      }
+      AddSummableValue(name + " Sum", sum);
+      if (supplierIndices.Count > 1)
+        AddString(name + " Avg", (sum/supplierIndices.Count).ToString(CultureInfo.InvariantCulture));
+    }
+
+
+    private void Populate(BioBoostCompoundSolution solution, string regionName) {
+      costsColumn2.DefaultCellStyle.Font = new Font("Lucida Console", 7);
+      costsColumn2.DefaultCellStyle.Format = "N0";
+      costsColumn2.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
+
+      costs = new Dictionary<string, double>();
+      values = new Dictionary<string, double>();
+      strings = new Dictionary<string, List<string>>();
+      foreach (var locationName in solution.LocationNames) {
+        if (regionName == BioBoostCompoundSolutionView.AllRegionsName || locationName.StartsWith(regionName))
+          AddRegion(solution, locationName);
+      }
+
+      var totalCost = 0d;
+      foreach (var cost in costs) {
+        costsDataGridView.Rows.Add(cost.Key, cost.Value);
+        totalCost += cost.Value;
+      }
+
+      foreach (var value in values) {
+        costsDataGridView.Rows.Add(value.Key, value.Value);
+      }
+
+      foreach (var value in strings) {
+        if (value.Value.Count == 1) {
+          double doubleValue;
+          if (Double.TryParse(value.Value[0], NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue)) {
+            costsDataGridView.Rows.Add(value.Key, doubleValue);
+          } else {
+          costsDataGridView.Rows.Add(value.Key, value.Value[0]);
+          }
+        } else {
+          //costsDataGridView.Rows.Add(value.Key, string.Join(",", value.Value));
+        }
+      }
+
+      /* var total = 0d;
+      foreach (var kvp in solution.DoubleValues) {
+        var name = kvp.Key;
+        if (name.EndsWith(BioBoostProblem.CostsName) || name.EndsWith(BioBoostProblem.CostName)) {
+          var sum = 0d;
+          for (int i = 0; i < kvp.Value.Length; i++) {
+            if (solution.LocationNames[i].StartsWith(regionName) || regionName.Equals(BioBoostCompoundSolutionView.AllRegionsName)) {
+              sum += kvp.Value[i];
+            }
+          }
+          if (name.EndsWith(BioBoostProblem.CostName)) {
+            name = name.Replace(BioBoostProblem.CostName, string.Empty);
+          } else {
+            name = name.Replace(BioBoostProblem.CostsName, string.Empty);
+          }
+          costsDataGridView.Rows.Add(name, sum);
+          total += sum;
+        }
+      } */
+      costsTextBox1.Text = totalCost.ToString("N0");
+    }
+
+    private void AddRegion(BioBoostCompoundSolution solution, string regionName) {
+      var supplierCollector = new SupplierCollector(solution, regionName);
+      foreach (var product in supplierCollector.Products) {
+        AddSummableValue(LayerDescriptor.ConverterCapacities.NameWithPrefix(product.Name), product.ConverterCapacity);
+        AddSummableValue(LayerDescriptor.StorageCapacities.NameWithPrefix(product.Name), product.StorageCapacity);
+        AddCost(LayerDescriptor.ConversionCosts.NameWithPrefix(product.Name), product.ConversionCost);
+        AddCost(LayerDescriptor.StorageCost.NameWithPrefix(product.Name), product.StorageCost);
+        AddCost(LayerDescriptor.ConversionPlantConstructionCost.NameWithPrefix(product.Name), product.ConversionPlantConstructionCost);
+        AddCost(LayerDescriptor.ConversionPlantOperationCost.NameWithPrefix(product.Name), product.ConversionPlantOperationCost);
+        AddString(LayerDescriptor.TransportTargets.NameWithPrefix(product.Name), product.TargetName);
+        AddSupplierValues(LayerDescriptor.AmountsTransportedFromSource.NameWithPrefix(product.Name), product.TransportedAmounts, product.SuppliersIndices);
+        AddSupplierValues(LayerDescriptor.TransportDistance.NameWithPrefix(product.Name), product.TransportDistances, product.SuppliersIndices);
+        AddSupplierValues(LayerDescriptor.Tkm.NameWithPrefix(product.Name), product.Tkm, product.SuppliersIndices);
+        AddSupplierValues(LayerDescriptor.RelativeCostAtSource.NameWithPrefix(product.Name), product.RelativeProductionCosts, product.SuppliersIndices); // TODO: really?
+        AddSupplierCosts(LayerDescriptor.TotalCostsAtSource.NameWithPrefix(product.Name), product.AcquisitionCosts, product.SuppliersIndices);
+        AddSupplierCosts(LayerDescriptor.DischargeCosts.NameWithPrefix(product.Name), product.DischargeCosts, product.SuppliersIndices);
+        AddSupplierCosts(LayerDescriptor.TransportCosts.NameWithPrefix(product.Name), product.TransportCosts, product.SuppliersIndices);
+        AddSupplierCosts(LayerDescriptor.HandlingCosts.NameWithPrefix(product.Name), product.HandlingCosts, product.SuppliersIndices);
+      }
+    }
+
+    private void Clear() {
+      costsDataGridView.Rows.Clear();
+      costsTextBox1.Text = string.Empty;
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionCostsView.resx	(revision 13072)
@@ -0,0 +1,126 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="costsColumn1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+  <metadata name="costsColumn2.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.Designer.cs	(revision 13072)
@@ -0,0 +1,124 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostSolutionDetailView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.GroupBox plantsGroupBox;
+      System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("AT111 (100t/a)");
+      System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("AT112 (200t/a)");
+      System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("FP (1000t/a)", new System.Windows.Forms.TreeNode[] {
+            treeNode1,
+            treeNode2});
+      System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("HTC");
+      System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("CP");
+      this.plantsTreeView = new System.Windows.Forms.TreeView();
+      this.regionNameLabel = new System.Windows.Forms.LinkLabel();
+      this.regionDescriptionLabel = new System.Windows.Forms.Label();
+      plantsGroupBox = new System.Windows.Forms.GroupBox();
+      plantsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // plantsGroupBox
+      // 
+      plantsGroupBox.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)));
+      plantsGroupBox.Controls.Add(this.plantsTreeView);
+      plantsGroupBox.Location = new System.Drawing.Point(3, 30);
+      plantsGroupBox.Name = "plantsGroupBox";
+      plantsGroupBox.Size = new System.Drawing.Size(286, 536);
+      plantsGroupBox.TabIndex = 4;
+      plantsGroupBox.TabStop = false;
+      plantsGroupBox.Text = "Plant Configurations";
+      // 
+      // plantsTreeView
+      // 
+      this.plantsTreeView.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.plantsTreeView.Font = new System.Drawing.Font("Lucida Console", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.plantsTreeView.HotTracking = true;
+      this.plantsTreeView.Location = new System.Drawing.Point(7, 20);
+      this.plantsTreeView.Name = "plantsTreeView";
+      treeNode1.Name = "Node3";
+      treeNode1.Text = "AT111 (100t/a)";
+      treeNode2.Name = "AT112";
+      treeNode2.Text = "AT112 (200t/a)";
+      treeNode3.Name = "FP";
+      treeNode3.Text = "FP (1000t/a)";
+      treeNode4.Name = "HTC";
+      treeNode4.Text = "HTC";
+      treeNode5.Name = "CP";
+      treeNode5.Text = "CP";
+      this.plantsTreeView.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
+            treeNode3,
+            treeNode4,
+            treeNode5});
+      this.plantsTreeView.Size = new System.Drawing.Size(273, 510);
+      this.plantsTreeView.TabIndex = 0;
+      this.plantsTreeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.plantsTreeView_NodeMouseDoubleClick);
+      // 
+      // regionNameLabel
+      // 
+      this.regionNameLabel.ActiveLinkColor = System.Drawing.Color.Red;
+      this.regionNameLabel.Dock = System.Windows.Forms.DockStyle.Top;
+      this.regionNameLabel.Location = new System.Drawing.Point(0, 0);
+      this.regionNameLabel.Name = "regionNameLabel";
+      this.regionNameLabel.Size = new System.Drawing.Size(292, 14);
+      this.regionNameLabel.TabIndex = 0;
+      this.regionNameLabel.TabStop = true;
+      this.regionNameLabel.Text = "AT111";
+      this.regionNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      this.regionNameLabel.Click += new System.EventHandler(this.regionNameLabel_Click);
+      // 
+      // regionDescriptionLabel
+      // 
+      this.regionDescriptionLabel.Dock = System.Windows.Forms.DockStyle.Top;
+      this.regionDescriptionLabel.Location = new System.Drawing.Point(0, 14);
+      this.regionDescriptionLabel.MaximumSize = new System.Drawing.Size(500, 13);
+      this.regionDescriptionLabel.Name = "regionDescriptionLabel";
+      this.regionDescriptionLabel.Size = new System.Drawing.Size(292, 13);
+      this.regionDescriptionLabel.TabIndex = 8;
+      this.regionDescriptionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // BioBoostSolutionDetailView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(plantsGroupBox);
+      this.Controls.Add(this.regionDescriptionLabel);
+      this.Controls.Add(this.regionNameLabel);
+      this.Name = "BioBoostSolutionDetailView";
+      this.Size = new System.Drawing.Size(292, 569);
+      plantsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TreeView plantsTreeView;
+    private System.Windows.Forms.LinkLabel regionNameLabel;
+    private System.Windows.Forms.Label regionDescriptionLabel;
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.cs	(revision 13072)
@@ -0,0 +1,133 @@
+﻿using System.Globalization;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using SharpMap.Data;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof(RegionDetailData), IsDefaultView = false)]
+  public partial class BioBoostSolutionDetailView : ItemView {
+
+    public new RegionDetailData Content {
+      get { return (RegionDetailData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public BioBoostSolutionDetailView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      plantsTreeView.Enabled = Content != null;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        Clear();
+      } else {
+        Clear();
+        Populate(Content.Solution, Content.RegionName);
+      }
+    }
+
+    public event EventHandler RegionLabelClicked;
+
+    protected void OnRegionLabelClicked() {
+      EventHandler h = RegionLabelClicked;
+      if (h != null)
+        h.Invoke(this, EventArgs.Empty);
+    }
+
+    private void Populate(BioBoostCompoundSolution solution, string regionName) {
+      regionNameLabel.Text = regionName; regionDescriptionLabel.Text = GetRegionDescription(regionName);
+      var locidx = solution.LocationNames.IndexOfFirst(s => s == regionName);
+      if (locidx < 0) return;
+      var supplierCollector = new SupplierCollector(solution, regionName);
+      foreach (var feedstock in supplierCollector.Feedstocks)
+        AddFeedstock(feedstock);
+      foreach (var product in supplierCollector.Products)
+        AddPlant(product);
+    }
+
+    private void Clear() {
+      regionNameLabel.Text = "";
+      regionDescriptionLabel.Text = "";
+      plantsTreeView.Nodes.Clear();
+    }
+
+    private void AddFeedstock(SupplierCollector.ProductInfo product) {
+      var potentialSeries = new Series(product.Name);
+      potentialSeries.Points.Add(product.Potential);
+      potentialSeries.ChartType = SeriesChartType.StackedBar100;
+    }
+
+    private void AddPlant(SupplierCollector.ProductInfo product) {
+      var totalAmount = product.Suppliers.Values.Sum();
+      if (totalAmount > 0) {
+        plantsTreeView.Nodes.Add(string.Format("{0} {1,11:### ### ###} t/a", product.Name, totalAmount));
+        foreach (var s in product.Suppliers)
+          AddSupplier(product.Name, s.Key, s.Value);
+      }
+    }
+
+    private void AddSupplier(string type, string sourceName, double feedstockAmount) {
+      foreach (TreeNode node in plantsTreeView.Nodes) {
+        if (node.Text.StartsWith(type)) {
+          node.Nodes.Add(string.Format(CultureInfo.InvariantCulture, "{0} {1,9:# ### ###} t/a", sourceName, feedstockAmount));
+          if (plantsTreeView.Nodes.Count == 1)
+            node.Expand();
+          else
+            plantsTreeView.CollapseAll();
+          break;
+        }
+      }
+    }
+
+    private string GetRegionDescription(string regionName) {
+      if (regionName != null && Content.Solution.Geometry.Features.Columns.Contains("name")) {
+        var row = Content.Solution.Geometry.Features.Rows.Cast<FeatureDataRow>().FirstOrDefault(r => (string)r["NUTS_ID"] == regionName);
+        if (row != null)
+          return row["name"].ToString();
+      }
+      return "";
+    }
+
+    private void plantsTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
+      if (e.Node.Parent != null) { // child node clicked
+        var labeltext = e.Node.Text.Split(' ');
+        if (labeltext.Length > 0)
+          TrySwitchToRegion(labeltext[0]);
+      }
+    }
+
+    private void TrySwitchToRegion(string regionName) {
+      if (Content.Solution.LocationNames.Contains(regionName)) {
+        Content = new RegionDetailData {
+          Solution = Content.Solution,
+          RegionName = regionName
+        };
+      }
+    }
+
+    private void regionNameLabel_Click(object sender, EventArgs e) {
+      OnRegionLabelClicked();
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionDetailView.resx	(revision 13072)
@@ -0,0 +1,123 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="plantsGroupBox.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>False</value>
+  </metadata>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionHistoryView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionHistoryView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionHistoryView.Designer.cs	(revision 13072)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostSolutionHistoryView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionHistoryView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionHistoryView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSolutionHistoryView.cs	(revision 13072)
@@ -0,0 +1,47 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof (ItemCollection<BioBoostCompoundSolution>), false)]
+  public partial class BioBoostSolutionHistoryView : MovieView<BioBoostCompoundSolution> {
+
+    private string firstFileName;
+    private readonly SaveFileDialog saveFileDialog = new SaveFileDialog();
+
+    public BioBoostSolutionHistoryView() {
+      InitializeComponent();
+    }
+
+    protected override void playButton_Click(object sender, EventArgs e) {
+      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
+        firstFileName = saveFileDialog.FileName;
+      }
+      base.playButton_Click(sender, e);
+    }
+
+    private static readonly Regex FILENAME_REGEX = new Regex(@"(.*)(-\d+)?(\.png)?", RegexOptions.IgnoreCase);
+
+    protected override void trackBar_ValueChanged(object sender, EventArgs e) {
+      base.trackBar_ValueChanged(sender, e);
+      var solution = viewHost.Content as BioBoostCompoundSolution;
+      var view = viewHost.ActiveView as BioBoostCompoundSolutionView;
+      if (view != null && solution != null) {
+        var filename = firstFileName.Replace(".png", string.Format("-{0:000000}.png", trackBar.Value));
+        view.SaveMapViewToPNG(filename);
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.Designer.cs	(revision 13072)
@@ -0,0 +1,155 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class BioBoostSummaryView {
+    /// <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.splitContainer1 = new System.Windows.Forms.SplitContainer();
+      this.treeView = new System.Windows.Forms.TreeView();
+      this.gridView = new System.Windows.Forms.DataGridView();
+      this.NameColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      this.ValueColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      this.valueLabel = new System.Windows.Forms.Label();
+      this.regionLabel = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+      this.splitContainer1.Panel1.SuspendLayout();
+      this.splitContainer1.Panel2.SuspendLayout();
+      this.splitContainer1.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.gridView)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // splitContainer1
+      // 
+      this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer1.Name = "splitContainer1";
+      // 
+      // splitContainer1.Panel1
+      // 
+      this.splitContainer1.Panel1.Controls.Add(this.valueLabel);
+      this.splitContainer1.Panel1.Controls.Add(this.treeView);
+      // 
+      // splitContainer1.Panel2
+      // 
+      this.splitContainer1.Panel2.Controls.Add(this.regionLabel);
+      this.splitContainer1.Panel2.Controls.Add(this.gridView);
+      this.splitContainer1.Size = new System.Drawing.Size(1041, 624);
+      this.splitContainer1.SplitterDistance = 421;
+      this.splitContainer1.TabIndex = 0;
+      // 
+      // treeView
+      // 
+      this.treeView.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.treeView.Location = new System.Drawing.Point(0, 21);
+      this.treeView.Name = "treeView";
+      this.treeView.Size = new System.Drawing.Size(419, 603);
+      this.treeView.TabIndex = 0;
+      this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
+      // 
+      // gridView
+      // 
+      this.gridView.AllowUserToAddRows = false;
+      this.gridView.AllowUserToDeleteRows = false;
+      this.gridView.AllowUserToResizeRows = false;
+      this.gridView.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.gridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
+      this.gridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.gridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+            this.NameColumn,
+            this.ValueColumn});
+      this.gridView.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
+      this.gridView.Location = new System.Drawing.Point(0, 21);
+      this.gridView.Name = "gridView";
+      this.gridView.ReadOnly = true;
+      this.gridView.RowHeadersVisible = false;
+      this.gridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
+      this.gridView.Size = new System.Drawing.Size(616, 603);
+      this.gridView.TabIndex = 0;
+      this.gridView.CurrentCellChanged += new System.EventHandler(this.gridView_CurrentCellChanged);
+      // 
+      // NameColumn
+      // 
+      this.NameColumn.HeaderText = "Name";
+      this.NameColumn.Name = "NameColumn";
+      this.NameColumn.ReadOnly = true;
+      this.NameColumn.Width = 60;
+      // 
+      // ValueColumn
+      // 
+      this.ValueColumn.HeaderText = "Value";
+      this.ValueColumn.Name = "ValueColumn";
+      this.ValueColumn.ReadOnly = true;
+      this.ValueColumn.Width = 59;
+      // 
+      // valueLabel
+      // 
+      this.valueLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.valueLabel.Location = new System.Drawing.Point(3, 0);
+      this.valueLabel.Name = "valueLabel";
+      this.valueLabel.Size = new System.Drawing.Size(416, 18);
+      this.valueLabel.TabIndex = 1;
+      this.valueLabel.Text = "no value layer selected";
+      this.valueLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // regionLabel
+      // 
+      this.regionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.regionLabel.Location = new System.Drawing.Point(3, 0);
+      this.regionLabel.Name = "regionLabel";
+      this.regionLabel.Size = new System.Drawing.Size(610, 18);
+      this.regionLabel.TabIndex = 2;
+      this.regionLabel.Text = "no region selected";
+      this.regionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // BioBoostSummaryView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer1);
+      this.Name = "BioBoostSummaryView";
+      this.Size = new System.Drawing.Size(1041, 624);
+      this.splitContainer1.Panel1.ResumeLayout(false);
+      this.splitContainer1.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+      this.splitContainer1.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.gridView)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.SplitContainer splitContainer1;
+    private System.Windows.Forms.TreeView treeView;
+    private System.Windows.Forms.DataGridView gridView;
+    private System.Windows.Forms.DataGridViewTextBoxColumn NameColumn;
+    private System.Windows.Forms.DataGridViewTextBoxColumn ValueColumn;
+    private System.Windows.Forms.Label valueLabel;
+    private System.Windows.Forms.Label regionLabel;
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.cs	(revision 13072)
@@ -0,0 +1,190 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [Content(typeof(RegionDetailData), IsDefaultView = false)]
+  public partial class BioBoostSummaryView : ItemView {
+
+    public new RegionDetailData Content {
+      get { return (RegionDetailData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public BioBoostSummaryView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        Clear();
+      } else {
+        Clear();
+        Populate();
+      }
+    }
+
+    protected void Clear() {
+      treeView.Nodes.Clear();
+      gridView.Rows.Clear();
+      regionLabel.Text = "no region selected";
+      valueLabel.Text = "no value selected";
+    }
+
+    protected void Populate() {
+      foreach (var targets in Content.Solution.TransportTargets) {
+        var node = treeView.Nodes.Add(targets.Key);
+        node.Tag = node.Text;
+        for (int i = 0; i < targets.Value.Length; i++) {
+          if (targets.Value[i] != null && targets.Value[i].Count > 0) {
+            var innerNode = node.Nodes.Add(Content.Solution.LocationNames[i]);
+            innerNode.Tag = innerNode.Text;
+            foreach (var suppliers in targets.Value[i]) {
+              var supplierNode = innerNode.Nodes.Add(Content.Solution.LocationNames[suppliers.Value]);
+              supplierNode.Tag = supplierNode.Text;
+            }
+          }
+        }
+      }
+      valueLabel.Text = "no value selected";
+      regionLabel.Text = Content.RegionName ?? "no region selected";
+    }
+
+    private void treeView_AfterSelect(object sender, TreeViewEventArgs e) {
+      gridView.Rows.Clear();
+      if (treeView.SelectedNode != null) {
+        var i = GetLocationIndex((string)treeView.SelectedNode.Tag);
+        if (i >= 0) {
+          PopulateGridView(i);
+        }
+      }
+    }
+
+    private int GetLocationIndex(string regionName) {
+      return Content.Solution.LocationNames.IndexOfFirst(x => x == regionName);
+    }
+
+    private double? GetValue(string regionName, string valueName) {
+      if (valueName == null) return null;
+      var i = GetLocationIndex(regionName);
+      if (i < 0) return 0;
+      DoubleArray doubles;
+      IntArray ints;
+      if (Content.Solution.DoubleValues.TryGetValue(valueName, out doubles)) {
+        return doubles[i];
+      } else if (Content.Solution.IntValues.TryGetValue(valueName, out ints)) {
+        return ints[i];
+      }
+      return null;
+    }
+
+    private void PopulateGridView(int index) {
+      regionLabel.Text = Content.Solution.LocationNames[index];
+      foreach (var kvp in Content.Solution.DoubleValues.Where(kvp => kvp.Value[index] != 0)) {
+        gridView.Rows.Add(kvp.Key, kvp.Value[index]);
+      }
+      foreach (var kvp in Content.Solution.IntValues.Where(kvp => kvp.Value[index] != 0)) {
+        gridView.Rows.Add(kvp.Key, kvp.Value[index]);
+      }
+      foreach (var kvp in Content.Solution.StringValues.Where(kvp => !string.IsNullOrWhiteSpace(kvp.Value[index]))) {
+        gridView.Rows.Add(kvp.Key, kvp.Value[index]);
+      }
+      foreach (var kvp in from kvp
+                            in Content.Solution.TransportTargets
+                          where kvp.Value[index] != null
+                          let s = string.Join(", ", kvp.Value[index])
+                          where !string.IsNullOrWhiteSpace(s) select kvp) {
+        gridView.Rows.Add(kvp.Key, string.Join(", ", kvp.Value[index]));
+      }
+      gridView.Sort(NameColumn, ListSortDirection.Ascending);
+    }
+
+    private void gridView_CurrentCellChanged(object sender, EventArgs e) {
+      string valueName = null;
+      if (gridView.SelectedRows.Count > 0) {
+        valueName = (string) gridView.SelectedRows[0].Cells[0].Value;
+      }
+      foreach (TreeNode rootNodes in treeView.Nodes) {
+        UpdateAggregatedValues(rootNodes, valueName);
+      }
+    }
+
+    private static string F(double value, int significantDigits = 6) {
+      int msd = (int)Math.Ceiling(Math.Log10(value));
+      int decimals = 6 - msd;
+      if (decimals <= 0) {
+        return value.ToString("### ### ### ### ### ### ### ### ### ### ### ### ###", CultureInfo.InvariantCulture);
+      } else if (decimals > significantDigits) {
+        return value.ToString("g2");
+      } else {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < msd; i+=3) {
+          if (sb.Length > 0) sb.Append(" ");
+          sb.Append("###");
+        }
+        sb.Append(".");
+        for (int i = 0; i < decimals; i += 3) {
+          if (sb[sb.Length-1] != '.') sb.Append(" ");
+          sb.Append("###");
+        }
+        return value.ToString(sb.ToString(), CultureInfo.InvariantCulture);
+      }
+    }
+
+    private double UpdateAggregatedValues(TreeNode node, string valueName) {
+      valueLabel.Text = valueName;
+      if (node.Nodes.Count == 0) {
+        var value = GetValue((string) node.Tag, valueName);
+        if (value.HasValue) {
+          node.Text = string.Format("{0} ({1})", node.Tag, F(value.Value));
+          return value.Value;
+        }
+        return 0;
+      }
+      double sum = 0;
+      int count = 0;
+      foreach (TreeNode subnode in node.Nodes) {
+        var subvalue = UpdateAggregatedValues(subnode, valueName);
+        sum += subvalue;
+        count++;
+      }
+      if (sum != 0) {
+        node.Text = string.Format("{0}   ({1} total,   {2} avg,    {3} count)", node.Tag, F(sum), F(sum/count), F(count));
+      } else {
+        var value = GetValue((string) node.Tag, valueName);
+        if (value.HasValue) {
+          node.Text = string.Format("{0} ({1})", node.Tag, F(value.Value));
+          return value.Value;
+        }
+        node.Text = (string) node.Tag;
+      }
+      return sum;
+    }
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/BioBoostSummaryView.resx	(revision 13072)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/EnumerableExtentions.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/EnumerableExtentions.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/EnumerableExtentions.cs	(revision 13072)
@@ -0,0 +1,20 @@
+﻿using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.BioBoost.Views {
+  public static class EnumerableExtentions {
+    /// <summary>
+    /// Returns the index of the first element in source matched by predicate.
+    /// </summary>
+    public static int IndexOfFirst<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
+      int i = 0;
+      foreach (T item in source) {
+        if (predicate(item)) {
+          return i;
+        }
+        i++;
+      }
+      return -1;
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.Designer.cs	(revision 13072)
@@ -0,0 +1,139 @@
+﻿namespace HeuristicLab.BioBoost.Views {
+  partial class FilterDialog {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterDialog));
+      this.label1 = new System.Windows.Forms.Label();
+      this.textBox1 = new System.Windows.Forms.TextBox();
+      this.keepOption = new System.Windows.Forms.RadioButton();
+      this.removeOption = new System.Windows.Forms.RadioButton();
+      this.okButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.errorProvider1 = new System.Windows.Forms.ErrorProvider(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.label1.Location = new System.Drawing.Point(13, 13);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(445, 48);
+      this.label1.TabIndex = 0;
+      this.label1.Text = resources.GetString("label1.Text");
+      // 
+      // textBox1
+      // 
+      this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.textBox1.Location = new System.Drawing.Point(12, 89);
+      this.textBox1.Name = "textBox1";
+      this.textBox1.Size = new System.Drawing.Size(446, 20);
+      this.textBox1.TabIndex = 1;
+      this.textBox1.Text = "^(FR|BE|NL|LU)";
+      this.textBox1.Validating += new System.ComponentModel.CancelEventHandler(this.textBox1_Validating);
+      this.textBox1.Validated += new System.EventHandler(this.textBox1_Validated);
+      // 
+      // keepOption
+      // 
+      this.keepOption.AutoSize = true;
+      this.keepOption.Checked = true;
+      this.keepOption.Location = new System.Drawing.Point(12, 118);
+      this.keepOption.Name = "keepOption";
+      this.keepOption.Size = new System.Drawing.Size(49, 17);
+      this.keepOption.TabIndex = 2;
+      this.keepOption.TabStop = true;
+      this.keepOption.Text = "&keep";
+      this.keepOption.UseVisualStyleBackColor = true;
+      this.keepOption.CheckedChanged += new System.EventHandler(this.keepOption_CheckedChanged);
+      // 
+      // removeOption
+      // 
+      this.removeOption.AutoSize = true;
+      this.removeOption.Location = new System.Drawing.Point(67, 118);
+      this.removeOption.Name = "removeOption";
+      this.removeOption.Size = new System.Drawing.Size(60, 17);
+      this.removeOption.TabIndex = 3;
+      this.removeOption.Text = "&remove";
+      this.removeOption.UseVisualStyleBackColor = true;
+      this.removeOption.CheckedChanged += new System.EventHandler(this.keepOption_CheckedChanged);
+      // 
+      // okButton
+      // 
+      this.okButton.Location = new System.Drawing.Point(383, 115);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 5;
+      this.okButton.Text = "&OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.okButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // cancelButton
+      // 
+      this.cancelButton.Location = new System.Drawing.Point(302, 115);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 4;
+      this.cancelButton.Text = "&Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+      // 
+      // errorProvider1
+      // 
+      this.errorProvider1.ContainerControl = this;
+      // 
+      // FilterDialog
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(470, 148);
+      this.ControlBox = false;
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.Controls.Add(this.removeOption);
+      this.Controls.Add(this.keepOption);
+      this.Controls.Add(this.textBox1);
+      this.Controls.Add(this.label1);
+      this.Name = "FilterDialog";
+      this.Text = "Filter Regions";
+      this.TopMost = true;
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.TextBox textBox1;
+    private System.Windows.Forms.RadioButton keepOption;
+    private System.Windows.Forms.RadioButton removeOption;
+    private System.Windows.Forms.Button okButton;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.ErrorProvider errorProvider1;
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.cs	(revision 13072)
@@ -0,0 +1,67 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+using System.Windows.Forms.VisualStyles;
+
+namespace HeuristicLab.BioBoost.Views {
+  public partial class FilterDialog : Form {
+
+    public Regex Regex { get; private set; }
+    public bool Keep { get; private set; }
+
+    public FilterDialog() {
+      InitializeComponent();
+      Keep = true;
+    }
+
+    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
+      if (keyData == Keys.Enter) {
+        DialogResult = DialogResult.OK;
+        Close();
+        return true;
+      } else if (keyData == Keys.Escape) {
+        DialogResult = DialogResult.Cancel;
+        Close();
+        return true;
+      }
+      return base.ProcessCmdKey(ref msg, keyData);
+    }
+
+    private void textBox1_Validating(object sender, CancelEventArgs e) {
+      try {
+        Regex = new Regex(textBox1.Text, RegexOptions.IgnoreCase|RegexOptions.IgnorePatternWhitespace);
+      } catch (ArgumentException x) {
+        textBox1.Select(0, textBox1.Text.Length);
+        e.Cancel = true;
+        errorProvider1.SetError(textBox1, "not a valid regular expression.");
+      }
+    }
+
+    private void textBox1_Validated(object sender, EventArgs e) {
+      errorProvider1.SetError(textBox1, "");
+    }
+
+    private void cancelButton_Click(object sender, EventArgs e) {
+      DialogResult = DialogResult.Cancel;
+      Close();
+    }
+
+    private void okButton_Click(object sender, EventArgs e) {
+      DialogResult = DialogResult.OK;
+      Close();
+    }
+
+    private void keepOption_CheckedChanged(object sender, EventArgs e) {
+      Keep = keepOption.Checked;
+    }
+
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/FilterDialog.resx	(revision 13072)
@@ -0,0 +1,127 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="label1.Text" xml:space="preserve">
+    <value>Filter data according to region names. You can specify a regular expression for either the region names to keep, or the region names to remove.
+For example: '^(FR|BE|NL|LU)' selects France, Belgium, the Netherlands and Luxemburg.</value>
+  </data>
+  <metadata name="errorProvider1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/GeometryExtensions.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/GeometryExtensions.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/GeometryExtensions.cs	(revision 13072)
@@ -0,0 +1,17 @@
+﻿using GeoAPI.Geometries;
+using System.Collections.Generic;
+
+namespace HeuristicLab.BioBoost.Views {
+  public static class GeometryExtensions {
+    public static IGeometry[] ToArray(this IGeometry geom) {
+      var results = new IGeometry[geom.NumGeometries];
+      for (int i=0; i<results.Length; i++)
+        results[i] = geom.GetGeometryN(i);
+      return results;
+    }
+    public static IEnumerable<IGeometry> GetGeometries(this IGeometry geom) {
+      for (int i = 0; i<geom.NumGeometries; i++)
+        yield return geom.GetGeometryN(i);
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/HeuristicLab.Problems.BioBoost.Views-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/HeuristicLab.Problems.BioBoost.Views-3.3.csproj	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/HeuristicLab.Problems.BioBoost.Views-3.3.csproj	(revision 13072)
@@ -0,0 +1,404 @@
+﻿<?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>{473AB0CD-0B71-471D-968C-A543B197E134}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.BioBoost.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.BioBoost.Views-3.3</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>
+  </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>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.BioBoost.Views.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>
+    <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>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.BioBoost.Views.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>false</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>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.BioBoost.Views.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>
+    <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>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.BioBoost.Views.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>false</CodeAnalysisIgnoreBuiltInRules>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>false</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="BruTile, Version=0.7.4.4, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\BruTile.0.7.4.4\lib\net40\BruTile.dll</HintPath>
+    </Reference>
+    <Reference Include="BruTile.Desktop, Version=0.7.4.4, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\BruTile.0.7.4.4\lib\net40\BruTile.Desktop.dll</HintPath>
+    </Reference>
+    <Reference Include="BruTile.MbTiles, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\BruTile.0.7.4.4\lib\net40\BruTile.MbTiles.dll</HintPath>
+    </Reference>
+    <Reference Include="BruTile.Serialization, Version=0.7.4.4, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\BruTile.0.7.4.4\lib\net40\BruTile.Serialization.dll</HintPath>
+    </Reference>
+    <Reference Include="Common.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=af08829b84f0328e, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\Common.Logging.2.0.0\lib\2.0\Common.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="GeoAPI, Version=1.7.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\GeoAPI.1.7.2\lib\net403-client\GeoAPI.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core.Views-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Core.Views-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">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.IntegerVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.IntegerVectorEncoding-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.MainForm.WindowsForms-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>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimizer-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Optimizer-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86">
+      <SpecificVersion>False</SpecificVersion>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="NetTopologySuite, Version=1.13.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\NetTopologySuite.1.13.2\lib\net403-client\NetTopologySuite.dll</HintPath>
+    </Reference>
+    <Reference Include="NetTopologySuite.IO.GeoTools, Version=1.13.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\NetTopologySuite.IO.1.13.2\lib\net403-client\NetTopologySuite.IO.GeoTools.dll</HintPath>
+    </Reference>
+    <Reference Include="NetTopologySuite.IO.MsSqlSpatial, Version=1.13.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\NetTopologySuite.IO.1.13.2\lib\net403-client\NetTopologySuite.IO.MsSqlSpatial.dll</HintPath>
+    </Reference>
+    <Reference Include="NetTopologySuite.IO.PostGis, Version=1.13.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\NetTopologySuite.IO.1.13.2\lib\net403-client\NetTopologySuite.IO.PostGis.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="PowerCollections, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\NetTopologySuite.1.13.2\lib\net403-client\PowerCollections.dll</HintPath>
+    </Reference>
+    <Reference Include="ProjNet, Version=1.3.0.3, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\ProjNET4GeoAPI.1.3.0.3\lib\net403-client\ProjNet.dll</HintPath>
+    </Reference>
+    <Reference Include="SharpMap, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\SharpMap.1.1.0\lib\net40-client\SharpMap.dll</HintPath>
+    </Reference>
+    <Reference Include="SharpMap.UI">
+      <HintPath>..\..\packages\SharpMap.UI.1.1.0\lib\net40-client\SharpMap.UI.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data.SQLite, Version=1.0.86.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\System.Data.SQLite.MSIL.1.0.86.0\lib\net45\System.Data.SQLite.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Data.SQLite.Linq, Version=1.0.86.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\System.Data.SQLite.MSIL.1.0.86.0\lib\net45\System.Data.SQLite.Linq.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BioBoostProblemDataView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostProblemDataView.Designer.cs">
+      <DependentUpon>BioBoostProblemDataView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BioBoostSolutionCostsView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostSolutionCostsView.Designer.cs">
+      <DependentUpon>BioBoostSolutionCostsView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BioBoostRegionDetailView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostRegionDetailView.Designer.cs">
+      <DependentUpon>BioBoostRegionDetailView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BioBoostSolutionDetailView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostSolutionDetailView.Designer.cs">
+      <DependentUpon>BioBoostSolutionDetailView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BioBoostCompoundSolutionEditor.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostCompoundSolutionEditor.Designer.cs">
+      <DependentUpon>BioBoostCompoundSolutionEditor.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BioBoostParetoSetView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostParetoSetView.Designer.cs">
+      <DependentUpon>BioBoostParetoSetView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BioBoostSolutionHistoryView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostSolutionHistoryView.Designer.cs">
+      <DependentUpon>BioBoostSolutionHistoryView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BioBoostSummaryView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostSummaryView.Designer.cs">
+      <DependentUpon>BioBoostSummaryView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="EnumerableExtentions.cs" />
+    <Compile Include="FilterDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="FilterDialog.Designer.cs">
+      <DependentUpon>FilterDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="GeometryExtensions.cs" />
+    <Compile Include="BioBoostCompoundSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BioBoostCompoundSolutionView.Designer.cs">
+      <DependentUpon>BioBoostCompoundSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="MapViews\GradientLegend.cs" />
+    <Compile Include="MapViews\ILazyLayerGenerator.cs" />
+    <Compile Include="MapViews\LazyVectorLayerGenerator.cs" />
+    <Compile Include="MapViews\LazyValueLayerGenerator.cs" />
+    <Compile Include="MenuItems\CreateBioBoostExperimentMenuItem.cs" />
+    <Compile Include="MenuItems\ExportSolutionMenuItem.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="RegionDetailData.cs" />
+    <Compile Include="SupplierCollector.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+    <None Include="Resources\WheatStraw.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\Transport.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\Coins.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\ShapefileIcon.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="BioBoostParetoSetView.resx">
+      <DependentUpon>BioBoostParetoSetView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="BioBoostProblemDataView.resx">
+      <DependentUpon>BioBoostProblemDataView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="BioBoostCompoundSolutionView.resx">
+      <DependentUpon>BioBoostCompoundSolutionView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="BioBoostSolutionCostsView.resx">
+      <DependentUpon>BioBoostSolutionCostsView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="BioBoostRegionDetailView.resx">
+      <DependentUpon>BioBoostRegionDetailView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="BioBoostSolutionDetailView.resx">
+      <DependentUpon>BioBoostSolutionDetailView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="BioBoostCompoundSolutionEditor.resx">
+      <DependentUpon>BioBoostCompoundSolutionEditor.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="BioBoostSummaryView.resx">
+      <DependentUpon>BioBoostSummaryView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterDialog.resx">
+      <DependentUpon>FilterDialog.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>PublicResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Resources\Farm-Fresh_arrow_divide.png" />
+    <Content Include="Resources\FeedstockCost.png" />
+    <Content Include="Resources\FoamingBeakerCartoon.png" />
+    <Content Include="Resources\neighbors.png" />
+    <Content Include="Resources\straw_bag.png" />
+    <Content Include="Resources\TransportAndStorageCost.png" />
+    <Content Include="Resources\TransportCost.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.BioBoost\3.3\HeuristicLab.Problems.BioBoost-3.3.csproj">
+      <Project>{61d4af50-8a40-44b9-9cd0-413f65d2235c}</Project>
+      <Name>HeuristicLab.Problems.BioBoost-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</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/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/GradientLegend.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/GradientLegend.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/GradientLegend.cs	(revision 13072)
@@ -0,0 +1,79 @@
+﻿using System.Drawing.Drawing2D;
+using SharpMap;
+using SharpMap.Rendering.Decoration;
+using System;
+using System.Drawing;
+
+using System.Globalization;
+
+
+namespace HeuristicLab.BioBoost.Views.MapViews {
+  public class GradientLegend : MapDecoration {
+    public Size Size { get; set; }
+    public double MinValue { get; set; }
+    public double MaxValue { get; set; }
+    public ColorBlend ColorBlend { get; set; }
+    public Point Offset { get; set; }
+    public Font Font { get; set; }
+    public String Unit { get; set; }
+
+    public GradientLegend() {
+      Size = new Size(150, 20);
+      Anchor = MapDecorationAnchor.LeftBottom;
+      MinValue = 0;
+      MaxValue = 1;
+      Offset = new Point(10, 10);
+      // color blend does not match the gradient legend exactly
+      /*
+       ColorBlend  = new ColorBlend {
+      Colors = new[] {
+        Color.FromArgb(0, 0, 127),
+        Color.FromArgb(0, 0, 255),
+        Color.FromArgb(0, 255, 255),
+        Color.FromArgb(0, 255, 0),
+        Color.FromArgb(127, 255, 0),
+        Color.FromArgb(255, 255, 0),
+        Color.FromArgb(255, 127, 0),
+        Color.FromArgb(255, 0, 0),
+        Color.FromArgb(127, 0, 0)},
+      Positions = new[] { 0.0f, 0.125f, 0.25f, 0.375f, 0.5f, 0.625f, 0.75f, 0.875f, 1f }
+       };
+       */
+      // GradientLegend uses ColorBlend from System.Drawing and we need to convert it to a SharpMap colorblend here
+      ColorBlend = new ColorBlend() {
+        Colors = LazyValueLayerGenerator.DefaultColorBlend.Colors,
+        Positions = LazyValueLayerGenerator.DefaultColorBlend.Positions
+      };
+      Font = (Font)SystemFonts.DefaultFont.Clone();
+    }
+
+    protected override Size InternalSize(Graphics g, Map map) {
+      return new Size(Size.Width + Offset.X + 4, Size.Height + Offset.Y + 3);
+    }
+
+    protected override void OnRender(Graphics g, Map map) {
+      var pos = new PointF(g.ClipBounds.Left + Offset.X, g.ClipBounds.Bottom - Offset.Y - Size.Height);
+      var brush = new System.Drawing.Drawing2D.LinearGradientBrush(pos, new PointF(pos.X + Size.Width, pos.Y), Color.Black, Color.Black) {
+        InterpolationColors = ColorBlend
+      };
+      g.FillRectangle(new SolidBrush(Color.FromArgb(127, 255, 255, 255)),
+        pos.X - 1, pos.Y - 1, Size.Width + 3, Size.Height + 2);
+      var minStr = MinValue.ToString(CultureInfo.InvariantCulture);
+      var maxStr = MaxValue.ToString("G4", CultureInfo.InvariantCulture);
+      if (!String.IsNullOrEmpty(Unit)) maxStr += " " + Unit;
+      var minDim = g.MeasureString(minStr, Font);
+      var maxDim = g.MeasureString(maxStr, Font);
+      var textHeight = Math.Min(minDim.Height, maxDim.Height);
+      g.FillRectangle(brush, pos.X, pos.Y + textHeight, Size.Width, Size.Height - textHeight - 2);
+      g.DrawString(minStr, Font, Brushes.Black, pos.X, pos.Y);
+      g.DrawString(maxStr, Font, Brushes.Black, pos.X + Size.Width - maxDim.Width - 2, pos.Y);
+      g.DrawLine(Pens.Black, pos.X, pos.Y, pos.X, pos.Y + Size.Height);
+      g.DrawLine(Pens.Black, pos.X + Size.Width, pos.Y, pos.X + Size.Width, pos.Y + Size.Height);
+
+      g.DrawLine(Pens.Black, pos.X + Size.Width / 4, pos.Y + textHeight, pos.X + Size.Width / 4, pos.Y + Size.Height);
+      g.DrawLine(Pens.Black, pos.X + Size.Width / 2, pos.Y + textHeight / 2, pos.X + Size.Width / 2, pos.Y + Size.Height);
+      g.DrawLine(Pens.Black, pos.X + Size.Width / 4 * 3, pos.Y + textHeight, pos.X + Size.Width / 4 * 3, pos.Y + Size.Height);
+    }
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/ILazyLayerGenerator.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/ILazyLayerGenerator.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/ILazyLayerGenerator.cs	(revision 13072)
@@ -0,0 +1,7 @@
+﻿using SharpMap.Layers;
+
+namespace HeuristicLab.BioBoost.Views.MapViews {
+  public interface ILazyLayerGenerator {
+    ILayer Layer { get;  }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/LazyValueLayerGenerator.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/LazyValueLayerGenerator.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/LazyValueLayerGenerator.cs	(revision 13072)
@@ -0,0 +1,129 @@
+﻿using GeoAPI.CoordinateSystems;
+using GeoAPI.Geometries;
+using NetTopologySuite.CoordinateSystems.Transformations;
+using NetTopologySuite.Geometries;
+using ProjNet.CoordinateSystems;
+using ProjNet.CoordinateSystems.Transformations;
+using SharpMap.Data;
+using SharpMap.Data.Providers;
+using SharpMap.Layers;
+using SharpMap.Rendering.Thematics;
+using SharpMap.Styles;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Linq;
+using ColorBlend = SharpMap.Rendering.Thematics.ColorBlend;
+
+namespace HeuristicLab.BioBoost.Views.MapViews {
+  public class LazyValueLayerGenerator : ILazyLayerGenerator {
+    public static ColorBlend DefaultColorBlend = new ColorBlend(new[] {
+        Color.FromArgb(0, 128, 255),
+        Color.FromArgb(0, 255, 255),
+        Color.FromArgb(0, 255, 0),
+        Color.FromArgb(128, 255, 0),
+        Color.FromArgb(255, 255, 0),
+        Color.FromArgb(255, 128, 0),
+      }, new[] { 0f, 1f / 5, 2f / 5, 3f / 5, 4f / 5, 1f });
+
+
+    private GeometryFeatureProvider geom;
+    private IEnumerable<string> locationNames;
+    private IEnumerable<double> values;
+    private ILayer layer;
+    public ColorBlend ColorBlend { get; set; }
+    public double? MinValue { get; set; }
+    public double? MaxValue { get; set; }
+    public double ActualMinValue { get; private set; }
+    public double ActualMaxValue { get; private set; }
+    public String LayerName { get; set; }
+    public bool RealtiveToSize { get; set; }
+    public string Unit { get; set; }
+    public Dictionary<string, double> Mapping; 
+
+    public LazyValueLayerGenerator(GeometryFeatureProvider geom, IEnumerable<string> locationNames, IEnumerable<double> values, String layerName) {
+      this.geom = geom;
+      this.locationNames = locationNames;
+      this.values = values;
+      this.LayerName = layerName;
+      this.RealtiveToSize = false;
+      this.ColorBlend = DefaultColorBlend;
+    }
+
+    public ILayer Layer {
+      get {
+        if (layer == null) BuildLayer();
+        return layer;
+      }
+    }
+
+    private void BuildLayer() {
+      string[] locationNames = this.locationNames.ToArray();
+      double[] values = this.values.ToArray();
+      this.locationNames = null;
+      this.values = null;
+      Mapping = locationNames
+        .Zip(values, (location, value) => new { location, value })
+        .ToDictionary(p => p.location, p => p.value);
+      if (RealtiveToSize) {
+        foreach (FeatureDataRow row in geom.Features.Rows) {
+          var nutsId = (string)row["NUTS_ID"];
+          double value;
+          if (Mapping.TryGetValue(nutsId, out value)) {
+            Mapping[nutsId] = value / GetAreaInHa(row.Geometry);
+          }
+        }
+      }
+      MinValue = MinValue ?? Mapping.Values.Min();
+      MaxValue = MaxValue ?? Mapping.Values.Max();
+      ActualMinValue = Math.Min(MinValue.Value, MaxValue.Value);
+      ActualMaxValue = Math.Max(MinValue.Value, MaxValue.Value);
+      var range = ActualMaxValue - ActualMinValue;
+      if (range == 0) range = 1;
+      layer = new VectorLayer(LayerName, geom) {
+        SmoothingMode = SmoothingMode.HighQuality,
+        Theme = new CustomTheme(row => {
+          var col = Color.LightGray;
+          double value;
+          if (row != null && Mapping.TryGetValue((string)row["NUTS_ID"], out value)) {
+            if (value != 0)
+              col = ColorBlend.GetColor((float)((value - ActualMinValue) / range));
+          }
+          return new VectorStyle {
+            Fill = new SolidBrush(col),
+            EnableOutline = true,
+            Outline = new Pen(Color.Black, 1f),
+          };
+        })
+      };
+
+    }
+
+    private static readonly CoordinateTransformationFactory transformFactory = new CoordinateTransformationFactory();
+    private static readonly CoordinateSystemFactory factory = new CoordinateSystemFactory();
+    private static double GetAreaInHa(IGeometry geom) {
+      geom = (IGeometry)geom.Clone();
+      var centroid = geom.Centroid;
+      var parameters = new List<ProjectionParameter> {
+        new ProjectionParameter("latitude_of_origin", centroid.Y),
+        new ProjectionParameter("central_meridian", centroid.X),
+        new ProjectionParameter("standard_parallel_1", 30),
+        new ProjectionParameter("standard_parallel_2", 75),
+        new ProjectionParameter("false_easting", 0),
+        new ProjectionParameter("false_northing", 0)
+      };
+      var projection = factory.CreateProjection("Albers", "albers_conic_equal_area", parameters);
+      var cartesian = factory.CreateProjectedCoordinateSystem(
+        "local albers",
+        GeographicCoordinateSystem.WGS84,
+        projection,
+        LinearUnit.Metre,
+        new AxisInfo("East", AxisOrientationEnum.East),
+        new AxisInfo("North", AxisOrientationEnum.North));
+      var transform = transformFactory.CreateFromCoordinateSystems(GeographicCoordinateSystem.WGS84, cartesian);
+      var transformed = GeometryTransform.TransformGeometry(GeometryFactory.Default, geom, transform.MathTransform);
+      return transformed.Area / 10000;
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/LazyVectorLayerGenerator.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/LazyVectorLayerGenerator.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MapViews/LazyVectorLayerGenerator.cs	(revision 13072)
@@ -0,0 +1,107 @@
+﻿using System.Data;
+using GeoAPI.Geometries;
+using NetTopologySuite.Geometries;
+using SharpMap.Data;
+using SharpMap.Data.Providers;
+using SharpMap.Layers;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Linq;
+
+namespace HeuristicLab.BioBoost.Views.MapViews {
+  public class LazyVectorLayerGenerator : ILazyLayerGenerator {
+
+    private GeometryFeatureProvider geom;
+    private IEnumerable<string> locationNames;
+    private IEnumerable<int> transportTargets;
+    private IEnumerable<double> transportAmounts;
+    private ILayer layer;
+    public String LayerName { get; set; }
+    public Color VectorColor { get; set; }
+    public int LineOffset { get; set; }
+
+    public LazyVectorLayerGenerator(GeometryFeatureProvider geom,
+      IEnumerable<string> locationNames,
+      IEnumerable<int> transportTargets,
+      IEnumerable<double> transportAmounts,
+      Color vectorColor,
+      String layerName) {
+      this.geom = geom;
+      if (locationNames == null) throw new ArgumentNullException("locationNames");
+      if (transportTargets == null) throw new ArgumentNullException("transportTargets");
+      this.locationNames = locationNames;
+      this.transportTargets = transportTargets;
+      this.transportAmounts = transportAmounts;
+      this.VectorColor = vectorColor;
+      this.LayerName = layerName;
+    }
+
+    public ILayer Layer {
+      get {
+        if (layer == null) BuildLayer();
+        return layer;
+      }
+    }
+
+    private void BuildLayer() {
+      string[] locationNames = this.locationNames.ToArray();
+      int[] transportTargets = this.transportTargets.ToArray();
+      double[] transportAmounts = this.transportAmounts == null ? null : this.transportAmounts.ToArray();
+      this.locationNames = null;
+      this.transportTargets = null;
+      var nameIndex = locationNames.Select((loc, idx) => new { loc, idx }).ToDictionary(p => p.loc, p => p.idx);
+      var centroids = new Coordinate[locationNames.Length];
+      foreach (FeatureDataRow row in geom.Features) {
+        int idx;
+        if (nameIndex.TryGetValue((string)row["NUTS_ID"], out idx)) {
+          var centroid = row.Geometry.Centroid;
+          try {
+            if (!centroid.Within(row.Geometry)) centroid = row.Geometry.InteriorPoint;
+          } catch (Exception x) { }
+          centroids[idx] = centroid.Coordinate;
+        }
+      }
+      var dataTable = new FeatureDataTable();
+      dataTable.Columns.Add("NUTS_ID_SRC");
+      dataTable.Columns.Add("NUTS_ID_DEST");
+
+      // var transports = new Collection<IGeometry>();
+      // GeoAPI.GeometryServiceProvider.Instance = new NetTopologySuite.NtsGeometryServices();
+      // var f = GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory(4326);
+      for (int i = 0; i < locationNames.Length; i++) {
+        if (transportAmounts != null && transportAmounts[i] <= 0) continue;
+        IGeometry g = null;
+        var j = transportTargets[i];
+        var source = centroids[i];
+        if (source == null) continue;
+        if (i == j)
+          g = new NetTopologySuite.Geometries.Point(source);
+        if (j == -1) continue;
+        var target = j < centroids.Length && j >= 0 ? centroids[j] : null;
+        if (target != null)
+          g = new LineString(new[] { source, target });
+
+        var row = dataTable.NewRow();
+        row.Geometry = g;
+        row["NUTS_ID_SRC"] = locationNames[i];
+        row["NUTS_ID_DEST"] = locationNames[j];
+        dataTable.AddRow(row);
+      }
+
+      var geometryProv = new GeometryFeatureProvider(dataTable);
+      var vectorLayer = new VectorLayer(LayerName, geometryProv);
+      vectorLayer.SmoothingMode = SmoothingMode.HighQuality;
+      vectorLayer.Style.Line.SetLineCap(LineCap.NoAnchor, LineCap.ArrowAnchor, DashCap.Flat);
+      vectorLayer.Style.Line.CustomEndCap = new AdjustableArrowCap(3, 5);
+      vectorLayer.Style.Line.Color = VectorColor;
+      vectorLayer.Style.Line.Width = 1;
+      vectorLayer.Style.LineOffset = LineOffset;
+      vectorLayer.Style.PointColor = new SolidBrush(VectorColor);
+      vectorLayer.Style.PointSize = 2;
+      this.layer = vectorLayer;
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MenuItems/CreateBioBoostExperimentMenuItem.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MenuItems/CreateBioBoostExperimentMenuItem.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MenuItems/CreateBioBoostExperimentMenuItem.cs	(revision 13072)
@@ -0,0 +1,234 @@
+﻿using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimizer;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+using HeuristicLab.BioBoost.Data;
+using HeuristicLab.BioBoost.Evaluators;
+using HeuristicLab.BioBoost.Operators.Mutation;
+using HeuristicLab.BioBoost.ProblemDescription;
+using HeuristicLab.BioBoost.Utils;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Parameters;
+using MenuItem = HeuristicLab.MainForm.WindowsForms.MenuItem;
+
+
+namespace HeuristicLab.BioBoost.Views {
+  internal sealed class CreateBioBoostExperimentMenuItem : MenuItem, IOptimizerUserInterfaceItemProvider {
+    public override string Name {
+      get { return "Create BioBoost Experiment"; }
+    }
+
+    public override IEnumerable<string> Structure {
+      get { return new string[] { "&Edit" }; }
+    }
+
+    public override int Position {
+      get { return 1450; }
+    }
+
+    protected override void OnToolStripItemSet(EventArgs e) {
+      ToolStripItem.Enabled = false;
+    }
+
+    protected override void OnActiveViewChanged(object sender, EventArgs e) {
+      IContentView activeView = MainFormManager.MainForm.ActiveView as IContentView;
+      if (activeView == null) {
+        ToolStripItem.Enabled = false;
+        return;
+      }
+
+      var content = activeView.Content;
+      var algorithm = content as IAlgorithm;
+
+      ToolStripItem.Enabled = algorithm != null && algorithm.Problem is BioBoostProblem;
+    }
+
+    private enum Pathway { FP, CP, HTC };
+    private enum Region { BI, SK, BS, SE, SW, C, S, EU };
+    private enum Price { Cheap, Medium, Expensive };
+    private enum Implementation { Narrow, Normal, Broad };
+
+    private int nValues(Type t) { return Enum.GetValues(t).Length; }
+
+    public override void Execute() {
+      IContentView activeView = (IContentView)MainFormManager.MainForm.ActiveView;
+      var mainForm = ((MainForm.WindowsForms.MainForm) MainFormManager.MainForm);
+      var progress = mainForm.AddOperationProgressToContent(activeView.Content, "Generating Algorithm Configurations");
+      int n = nValues(typeof (Pathway))*nValues(typeof (Region))*nValues(typeof (Price))* nValues(typeof (Implementation));
+      int count = 0;
+      progress.Start();
+      progress.ProgressValue = 1.0*count/n;
+      var alg = activeView.Content as IAlgorithm;
+
+      Action<IContentView> action = view => {
+        var optimizers = new List<IOptimizer>();
+        foreach (Region r in Enum.GetValues(typeof (Region))) {
+          var x = new Experiment("BioBoost final experiment " + r);
+          foreach (Pathway pw in Enum.GetValues(typeof (Pathway))) {
+            foreach (Price p in Enum.GetValues(typeof (Price))) {
+              foreach (Implementation i in Enum.GetValues(typeof (Implementation))) {
+                x.Optimizers.Add(CreateConfiguration(alg, pw, r, p, i, true));
+                progress.ProgressValue = 1.0*(++count)/n;
+                //x.Optimizers.Add(CreateConfiguration(alg, pw, r, p, i, false));
+                //progress.Start(string.Format("{0}/{1}", count, n));
+              }
+            }
+          }
+          var br = new BatchRun("BioBoost final batch run " + r);
+          br.Repetitions = 3;
+          br.Optimizer = x;
+          optimizers.Add(br);
+        }
+        progress.Finish();
+        foreach (var opt in optimizers)
+          MainFormManager.MainForm.ShowContent(opt);
+      };
+
+
+      action.BeginInvoke(activeView, delegate(IAsyncResult result) {
+        try {
+          action.EndInvoke(result);
+        } catch (SystemException e) {
+          var dialog = new PluginInfrastructure.ErrorDialog(e);
+          dialog.ShowDialog();
+        }
+        mainForm.RemoveOperationProgressFromContent(activeView.Content);
+      }, null);
+
+    }
+
+    private static IAlgorithm CreateConfiguration(IAlgorithm alg, Pathway pw, Region r, Price p, Implementation i, bool limitedDistanceInit) {
+      alg = (IAlgorithm) alg.Clone();
+      var problem = alg.Problem as BioBoostProblem;
+      var problemData = problem.ProblemData;
+
+      switch (r) {
+        case Region.BI: problemData.KeepRegions(new Regex("^(UK|IE)")); break; // BI (British Islands)
+        case Region.SK: problemData.KeepRegions(new Regex("^(SE|FI)")); break; // SK (Scandinavia)
+        case Region.BS: problemData.KeepRegions(new Regex("^(EE|LV|LT)")); break; // BS (Baltic States)
+        case Region.SE: problemData.KeepRegions(new Regex("^(BG|RO|EL|MK)")); break; // SE (South East Europe)
+        case Region.SW: problemData.KeepRegions(new Regex("^(ES|PT|FR|NL|BE|LU)")); break; //SW (South West Europe)
+        case Region.C: problemData.KeepRegions(new Regex("^(DE|DK|PL|CZ|SK)")); break; // C (Central Europe)
+        case Region.S: problemData.KeepRegions(new Regex("^(AT|SI|HU|IT|HR)")); break; // S (South Central)
+        case Region.EU: /* don't remove anything */ break;
+      }
+
+      string feedstock = null;
+      string carrier = null;
+      string finalProduct = null;
+      switch (pw) {
+        case Pathway.FP: feedstock = "Straw"; carrier = "Biosyncrude"; finalProduct = "TransportFuel"; break;
+        case Pathway.CP: feedstock = "ForestryResidues"; carrier = "Biooil"; finalProduct = "TransportFuel"; break;
+        case Pathway.HTC: feedstock = "MunicipalWaste"; carrier = "Biocoal"; finalProduct = "ElectricityOut"; break;
+      }
+      SetPathway(problemData, feedstock, carrier, finalProduct);
+
+      switch (p) {
+        case Price.Cheap: ScaleFeedstockPrice(problemData, feedstock, 0.75); break;
+        case Price.Medium: ScaleFeedstockPrice(problemData, feedstock, 1); break;
+        case Price.Expensive:  ScaleFeedstockPrice(problemData, feedstock, 1.5); break;
+      }
+
+      double alpha = 1;
+      bool plantKiller = false;
+      switch (i) {
+        case Implementation.Narrow: alpha = 1; plantKiller = true; break;
+        case Implementation.Normal: alpha = 1; plantKiller = false; break;
+        case Implementation.Broad: alpha = 0.5; plantKiller = false; break;
+      }
+      ((MonolithicEvaluator) problem.Evaluator).AlphaParameter.Value = new DoubleValue(alpha);
+      var mutationOperators = ((MultiMutator) NavigateItem(alg, "Mutator")).Operators;
+      mutationOperators.SetItemCheckedState(mutationOperators.First(op => op.Name == "PlantKiller"), plantKiller);
+
+      if (limitedDistanceInit) {
+        Choose( (ConstrainedValueParameter<IIntegerVectorCreator>) NavigateParameter(problem, "SolutionCreator", "IntegerVectorCreator"), "LimitedDistanceTransportTargetCreator");
+        Set((IParameterizedItem) NavigateItem(problem, "SolutionCreator", "IntegerVectorCreator"), "TournamentSize", 20);
+      } else {
+        Choose((ConstrainedValueParameter<IIntegerVectorCreator>) NavigateParameter(problem, "SolutionCreator", "IntegerVectorCreator"), "UniformRandomIntegerVectorCreator");
+      }
+
+      // adjust generations
+      int n = problem.NRegions;
+      Set(alg, "MaximumGenerations", n*n);
+
+      alg.Name = string.Format("BioBoost 11a final {0} {1} {2} {3} {4} {5}Gen", pw, r, p, i, limitedDistanceInit ? "LimitedDistanceInit" : "", n*n);
+      return alg;
+    }
+
+    private static void ScaleFeedstockPrice(BioBoostProblemData problemData, string feedstockName, double scale) {
+      Scale((Product) NavigateItem(problemData, "DataItems", "Product: " + feedstockName), "Price", scale);
+      Scale((Product) NavigateItem(problemData, "DataItems", "Product: " + feedstockName), "MaxPrice", scale);
+    }
+
+    private static void SetPathway(BioBoostProblemData problemData, string feedstock, string carrier, string finalProduct) {
+      CheckOnly(problemData, "Utilizations", feedstock);
+      CheckOnly(problemData, "TransportTargets", feedstock, carrier);
+      CheckOnly(problemData, "FinalProducts", finalProduct);
+      var potentials = problemData.FeedstockPotentials.Select(p => p.Name).ToHashSet();
+      foreach (var p in potentials) {
+        if (p != feedstock + "Potentials") {
+          problemData.FeedstockPotentials.Remove(p);
+        }
+      }
+      foreach (var p in problemData.Products) {
+        if (potentials.Contains(p.Label + "Potentials") && p.Label != feedstock)
+          problemData.DataItems.Remove(p);
+      }
+    }
+
+
+    private static void Set(IParameterizedItem item, string name, double value) { ((IValueParameter<DoubleValue>)item.Parameters[name]).Value = new DoubleValue(value); }
+    private static void Set(IParameterizedItem item, string name, int value) { ((IValueParameter<IntValue>)item.Parameters[name]).Value = new IntValue(value); }
+
+    private static void Scale(IParameterizedItem item, string name, double scale) {
+      var value = ((IValueParameter<DoubleValue>) item.Parameters[name]).Value.Value;
+      ((IValueParameter<DoubleValue>)item.Parameters[name]).Value = new DoubleValue(value*scale);
+    }
+
+    private static void CheckOnly(IParameterizedItem item, string name, params string[] values) {
+      var valueSet = new HashSet<string>(values);
+      var parameters = ((ValueParameter<CheckedItemList<StringValue>>) item.Parameters[name]).Value;
+      foreach (var i in parameters) {
+        parameters.SetItemCheckedState(i, valueSet.Contains(i.Value));
+      }
+    }
+
+    private static IItem NavigateItem(IItem item, params string[] path) {
+      for (int i = 0; i < path.Length; i++) {
+        if (item is IParameterizedItem) {
+          item = ((IValueParameter) ((IParameterizedItem) item).Parameters[path[i]]).Value;
+        } else if (item is ItemCollection<DataItem>) {
+          item = ((ItemCollection<DataItem>) item).First(x => x.ToString() == path[i]);
+        }
+      }
+      return item;
+    }
+
+    private static IItem NavigateParameter(IItem item, params string[] path) {
+      for (int i = 0; i < path.Length; i++) {
+        item = ((IParameterizedItem) item).Parameters[path[i]];
+        if (i < path.Length-1)
+          item = ((IValueParameter) item).Value;
+      }
+      return item;
+    }
+
+    private static void Choose<T>(ConstrainedValueParameter<T> param, string valueName) where T : class, IItem {
+      param.Value = param.ValidValues.First(v => v.ItemName == valueName);
+    }
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MenuItems/ExportSolutionMenuItem.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MenuItems/ExportSolutionMenuItem.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/MenuItems/ExportSolutionMenuItem.cs	(revision 13072)
@@ -0,0 +1,177 @@
+﻿using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimizer;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using MenuItem = HeuristicLab.MainForm.WindowsForms.MenuItem;
+
+
+namespace HeuristicLab.BioBoost.Views {
+  internal sealed class ExportSolutionMenuItem : MenuItem, IOptimizerUserInterfaceItemProvider {
+    public override string Name {
+      get { return "Export CSV"; }
+    }
+
+    public override IEnumerable<string> Structure {
+      get { return new string[] { "&File" }; }
+    }
+
+    public override int Position {
+      get { return 1450; }
+    }
+
+    protected override void OnToolStripItemSet(EventArgs e) {
+      ToolStripItem.Enabled = false;
+    }
+
+    protected override void OnActiveViewChanged(object sender, EventArgs e) {
+      IContentView activeView = MainFormManager.MainForm.ActiveView as IContentView;
+      if (activeView == null) {
+        ToolStripItem.Enabled = false;
+        return;
+      }
+
+      var content = activeView.Content;
+      RunCollection runCollection = content as RunCollection;
+      var optimizer = content as IOptimizer;
+      if (runCollection == null && optimizer != null) {
+        runCollection = ((IOptimizer)content).Runs;
+      }
+
+      var alg = content as IAlgorithm;
+      var solution = content as BioBoostCompoundSolution;
+
+      ToolStripItem.Enabled =
+        // at least on run with a result || or the alg is paused and results contains a bioboost solution
+        (runCollection != null && runCollection.Any(run => run.Results.Any(p => p.Value is BioBoostCompoundSolution))) ||
+        (alg != null && alg.ExecutionState == ExecutionState.Paused && alg.Results.Any(r => r.Value is BioBoostCompoundSolution)) ||
+        (solution != null)
+        ;
+    }
+
+    public override void Execute() {
+      var folderBrowserDialog = new FolderBrowserDialog();
+      folderBrowserDialog.Description = "Select the export directory.";
+      folderBrowserDialog.RootFolder = Environment.SpecialFolder.Desktop;
+      if (folderBrowserDialog.ShowDialog() == DialogResult.OK) {
+        var folderName = folderBrowserDialog.SelectedPath;
+        IContentView activeView = (IContentView)MainFormManager.MainForm.ActiveView;
+        var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
+        mainForm.AddOperationProgressToContent(activeView.Content, "Export solutions.");
+
+        Action<IContentView> action = (view) => {
+          var i = 0;
+          // export the solutions of all runs
+          foreach (var run in view.Content.GetObjectGraphObjects(excludeStaticMembers: true).OfType<Run>()) {
+            var solution =
+              run.GetObjectGraphObjects(excludeStaticMembers: true).OfType<BioBoostCompoundSolution>().FirstOrDefault();
+            if (solution == null) continue;
+            ExportSolution(folderName, i++, run.Name, solution);
+          }
+          // export the solutions in the results of the paused algorithm
+          var alg = view.Content as IAlgorithm;
+          if (alg != null && alg.ExecutionState == ExecutionState.Paused) {
+            foreach (var solution in alg.Results.Select(r => r.Value).OfType<BioBoostCompoundSolution>()) {
+              ExportSolution(folderName, i++, alg.Name, solution);
+            }
+          }
+
+          // export the solution itself
+          var bioBoostSolution = view.Content as BioBoostCompoundSolution;
+          if (bioBoostSolution != null)
+            ExportSolution(folderName, i++, bioBoostSolution.Name, bioBoostSolution);
+        };
+
+        action.BeginInvoke(activeView, delegate(IAsyncResult result) {
+          try {
+            action.EndInvoke(result);
+          } catch (SystemException e) {
+            var dialog = new HeuristicLab.PluginInfrastructure.ErrorDialog(e);
+            dialog.ShowDialog();
+          }
+          mainForm.RemoveOperationProgressFromContent(activeView.Content);
+        }, null);
+      }
+    }
+
+    private void ExportSolution(string folderName, int i, string name, BioBoostCompoundSolution solution) {
+      var csv = CreateCsvSolution(solution);
+      var filename = string.Format("{0}-{1}.csv", i, name);
+      // remove invalid characters
+      foreach (var ch in Path.GetInvalidFileNameChars()) {
+        filename = filename.Replace(ch, '_');
+
+      }
+      var path = Path.Combine(folderName, filename);
+      if (path.Length >= 248) throw new PathTooLongException("The path is longer than 248 characters. Try to save your files in a different folder");
+      if (filename.Length >= 260) throw new PathTooLongException("The filename is longer than 260 characters. Please change the name of runs to something shorter.");
+      File.WriteAllText(path, csv);
+    }
+
+    private string CreateCsvSolution(BioBoostCompoundSolution content) {
+      content.EvaluateAndUpdateAllResults();
+      var sb = new StringBuilder();
+      // header
+      sb.Append("NUTS_ID").Append(",");
+      sb.Append(string.Join(",", content.IntValues.Select(x => string.Format("\"{0}\"", x.Key)))).Append(",");
+      sb.Append(string.Join(",", content.IntValues.Select(x => string.Format("\"{0}-Region\"", x.Key)))).Append(",");
+      sb.Append(string.Join(",", content.DoubleValues.Select(x => string.Format("\"{0}\"", x.Key)))).Append(",");
+      sb.Append(string.Join(",", content.StringValues.Select(x => string.Format("\"{0}\"", x.Key))));
+      sb.Append(Environment.NewLine);
+      // rows
+      for (int i = 0; i < content.LocationNames.Length; i++) {
+        sb.Append(content.LocationNames[i]);
+        foreach (var kvp in content.IntValues) { sb.Append(",").Append(kvp.Value[i].ToString("D", CultureInfo.InvariantCulture)); }
+        foreach (var kvp in content.IntValues) { sb.Append(",").Append(kvp.Value[i] < 0 ? "" : content.LocationNames[kvp.Value[i]]); }
+        foreach (var kvp in content.DoubleValues) { sb.Append(",").Append(kvp.Value[i].ToString("G", CultureInfo.InvariantCulture)); }
+        foreach (var kvp in content.StringValues) { sb.Append(",").Append(kvp.Value[i]); }
+        sb.Append(Environment.NewLine);
+      }
+
+      return sb.ToString();
+    }
+
+    /*
+    private string CreateJsonSolution(BioBoostCompoundSolution content) {
+      var builder = new StringBuilder();
+      builder.Append("{ \"type\": \"FeatureCollection\", \n\"features\": [");
+      for (int i = 0; i < content.LocationNames.Length; i++) {
+        if (i > 0) builder.Append(",");
+        builder.Append("\n{ \"type\": \"Feature\", \"properties\": { \"NUTS_ID\": \"");
+        builder.Append(content.LocationNames[i]);
+        builder.Append("\"");
+        foreach (var kvp in content.IntValues) {
+          var target = content.LocationNames[i];
+          if (kvp.Value[i] >= 0) {
+            target = content.LocationNames[kvp.Value[i]];
+          }
+          builder.Append(",\n                                     \"");
+          builder.Append(kvp.Key);
+          builder.Append("\": \"");
+          builder.Append(target);
+          builder.Append("\"");
+        }
+        foreach (var kvp in content.DoubleValues) {
+          builder.Append(",\n                                     \"");
+          builder.Append(kvp.Key);
+          builder.Append("\": ");
+          builder.Append(kvp.Value[i].ToString("R", CultureInfo.InvariantCulture));
+        }
+        builder.Append("} }");
+      }
+      builder.Append("\n]\n}");
+
+      return builder.ToString();
+    }
+    */
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Plugin.cs.frame	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Plugin.cs.frame	(revision 13072)
@@ -0,0 +1,16 @@
+﻿using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.BioBoost.Views {
+  [Plugin("HeuristicLab.Problems.BioBoost.Views", "HL views plugin for FP7 project BioBoost", "3.3.12.$WCREV$")]
+  [PluginFile("HeuristicLab.Problems.BioBoost.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Problems.BioBoost", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class Plugin : PluginBase {}
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 13072)
@@ -0,0 +1,35 @@
+﻿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.Problems.BioBoost.Views")]
+[assembly: AssemblyDescription("Views for the HeuristicLab BioBoost Plugin")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[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("c307fa4b-9c9e-4c13-812d-3213d24fc712")]
+
+// 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.12.$WCREV$")]
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/Resources.Designer.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/Resources.Designer.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/Resources.Designer.cs	(revision 13072)
@@ -0,0 +1,173 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HeuristicLab.Problems.BioBoost.Views.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    public class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        public static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HeuristicLab.Problems.BioBoost.Views.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        public static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap Coins {
+            get {
+                object obj = ResourceManager.GetObject("Coins", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap Farm_Fresh_arrow_divide {
+            get {
+                object obj = ResourceManager.GetObject("Farm_Fresh_arrow_divide", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap FeedstockCost {
+            get {
+                object obj = ResourceManager.GetObject("FeedstockCost", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap FoamingBeakerCartoon {
+            get {
+                object obj = ResourceManager.GetObject("FoamingBeakerCartoon", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap neighbors {
+            get {
+                object obj = ResourceManager.GetObject("neighbors", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap ShapefileIcon {
+            get {
+                object obj = ResourceManager.GetObject("ShapefileIcon", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap straw_bag {
+            get {
+                object obj = ResourceManager.GetObject("straw_bag", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap Transport {
+            get {
+                object obj = ResourceManager.GetObject("Transport", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap TransportAndStorageCost {
+            get {
+                object obj = ResourceManager.GetObject("TransportAndStorageCost", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap TransportCost {
+            get {
+                object obj = ResourceManager.GetObject("TransportCost", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap WheatStraw {
+            get {
+                object obj = ResourceManager.GetObject("WheatStraw", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+    }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/Resources.resx
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/Resources.resx	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/Properties/Resources.resx	(revision 13072)
@@ -0,0 +1,154 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="Coins" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\coins.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="FeedstockCost" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\feedstockcost.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="ShapefileIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\shapefileicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="straw_bag" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\straw_bag.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="Transport" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\transport.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="TransportCost" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\transportcost.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="WheatStraw" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\wheatstraw.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="TransportAndStorageCost" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\transportandstoragecost.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="FoamingBeakerCartoon" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\foamingbeakercartoon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="neighbors" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\neighbors.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="Farm_Fresh_arrow_divide" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\resources\farm-fresh_arrow_divide.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+</root>
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/RegionDetailData.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/RegionDetailData.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/RegionDetailData.cs	(revision 13072)
@@ -0,0 +1,48 @@
+﻿using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
+
+namespace HeuristicLab.BioBoost.Views {
+
+  [StorableClass]
+  public class RegionDetailData : ParameterizedNamedItem {
+
+    public override bool CanChangeName { get { return false; } }
+
+    #region Parameters
+    public ValueParameter<BioBoostCompoundSolution> SolutionParameter {
+      get { return (ValueParameter<BioBoostCompoundSolution>) Parameters["Solution"]; }
+    }
+    public ValueParameter<StringValue> RegionNameParameter {
+      get { return (ValueParameter<StringValue>) Parameters["RegionName"]; }
+    }
+    #endregion
+
+    #region Parameter Values
+    public BioBoostCompoundSolution Solution {
+      get { return SolutionParameter.Value; }
+      set { SolutionParameter.Value = value;  }
+    }
+    public String RegionName {
+      get { return RegionNameParameter.Value.Value; }
+      set { RegionNameParameter.Value.Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected RegionDetailData(bool isDeserializing) : base(isDeserializing) {}
+    protected RegionDetailData(RegionDetailData orig, Cloner cloner) : base(orig, cloner) {}
+    public RegionDetailData() {
+      Parameters.Add(new ValueParameter<BioBoostCompoundSolution>("Solution", "The solution from which the detail should be obtained."));
+      Parameters.Add(new ValueParameter<StringValue>("RegionName", "The name of the region for which details show be displayed."));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegionDetailData(this, cloner);
+    }
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/SupplierCollector.cs
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/SupplierCollector.cs	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/SupplierCollector.cs	(revision 13072)
@@ -0,0 +1,152 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using HeuristicLab.BioBoost.Representation;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.BioBoost.Views {
+
+
+  public class SupplierCollector {
+
+    public class ProductInfo {
+      public string Name;
+      public double Potential;
+      public double Utilization;
+      public double ConverterCapacity;
+      public double StorageCapacity;
+      public double ConversionCost;
+      public double StorageCost;
+      public double ConversionPlantConstructionCost;
+      public double ConversionPlantOperationCost;
+      public string TargetName;
+      public IntArray TransportTargts;
+      public DoubleArray TransportedAmounts;
+      public DoubleArray Utilizations;
+      public DoubleArray Potentials;
+      public DoubleArray AcquisitionCosts;
+      public DoubleArray DischargeCosts;
+      public DoubleArray TransportCosts;
+      public DoubleArray HandlingCosts;
+      public DoubleArray RelativeProductionCosts;
+      public DoubleArray TransportDistances;
+      public DoubleArray Tkm;
+      public StringArray TransportModes;
+      public Dictionary<string, double> Suppliers;
+      public List<int> SuppliersIndices;
+    }
+
+    public List<ProductInfo> Feedstocks { get; private set; }
+    public List<ProductInfo> Products { get; private set; }
+
+    public SupplierCollector(BioBoostCompoundSolution solution, string regionName) {
+      Feedstocks = new List<ProductInfo>();
+      Products = new List<ProductInfo>();
+      var locidx = solution.LocationNames.IndexOfFirst(s => s == regionName);
+      if (locidx < 0) return;
+      var products = new Dictionary<string, ProductInfo>();
+      foreach (var kvp in solution.DoubleValues) {
+        AddProductInfo(
+          products, kvp.Key, LayerDescriptor.PotentialsFromProblemData.FullName,
+          pi => {
+            pi.Potential = kvp.Value[locidx];
+            pi.Potentials = kvp.Value;
+          });
+        AddProductInfo(
+          products, kvp.Key, LayerDescriptor.Utilizations.FullName,
+          pi => {
+            pi.Utilization = kvp.Value[locidx];
+            pi.Utilizations = kvp.Value;
+          });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.AmountsTransportedFromSource.FullName, pi => { pi.TransportedAmounts = kvp.Value; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.TotalCostsAtSource.FullName, pi => { pi.AcquisitionCosts = kvp.Value; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.DischargeCosts.FullName, pi => { pi.DischargeCosts = kvp.Value; });
+        //AddProductInfo(products, kvp.Key, LayerDescriptor.TotalCostsAtSource.FullName, pi => { pi.Costs = kvp.Value; });
+        //AddProductInfo(products, kvp.Key, LayerDescriptor.TotalCostsAtTarget.FullName, pi => { pi.Costs = kvp.Value; });
+        //AddProductInfo(products, kvp.Key, LayerDescriptor.Costs.FullName, pi => { pi.Costs = kvp.Value; });
+        //AddProductInfo(products, kvp.Key, LayerDescriptor.AmountsAtSource.FullName + LayerDescriptor.Costs.FullName, pi => { pi.Costs = Add(pi.Costs, kvp.Value); });
+        //AddProductInfo(products, kvp.Key, LayerDescriptor.AmountsAtTarget.FullName + LayerDescriptor.Costs.FullName, pi => { pi.Costs = Add(pi.Costs, kvp.Value); });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.TransportCosts.FullName, pi => { pi.TransportCosts = kvp.Value; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.HandlingCosts.FullName, pi => { pi.HandlingCosts = kvp.Value; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.RelativeCostAtSource.FullName, pi => { pi.RelativeProductionCosts = kvp.Value; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.TransportDistance.FullName, pi => { pi.TransportDistances = kvp.Value; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.Tkm.FullName, pi => { pi.Tkm = kvp.Value; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.ConverterCapacities.FullName, pi => { pi.ConverterCapacity = kvp.Value[locidx]; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.StorageCapacities.FullName, pi => { pi.StorageCapacity = kvp.Value[locidx]; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.ConversionCosts.FullName, pi => { pi.ConversionCost = kvp.Value[locidx]; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.StorageCost.FullName, pi => { pi.StorageCost = kvp.Value[locidx]; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.ConversionPlantConstructionCost.FullName, pi => { pi.ConversionPlantConstructionCost = kvp.Value[locidx]; });
+        AddProductInfo(products, kvp.Key, LayerDescriptor.ConversionPlantOperationCost.FullName, pi => { pi.ConversionPlantOperationCost = kvp.Value[locidx]; });
+      }
+      foreach (var kvp in solution.IntValues) {
+        AddProductInfo(
+          products, kvp.Key, LayerDescriptor.TransportTargets.FullName,
+          pi => {
+            var target = kvp.Value[locidx];
+            pi.TargetName = target >= 0 ? solution.LocationNames[target] : "<none>";
+            pi.TransportTargts = kvp.Value;
+          });
+      }
+      if (solution.StringValues == null) {
+        foreach (var kvp in solution.StringValues) {
+          AddProductInfo(
+            products, kvp.Key, LayerDescriptor.TransportModes.FullName, pi => { pi.TransportModes = kvp.Value; });
+        }
+      }
+      foreach (var product in products.Values) {
+        product.Suppliers = new Dictionary<string, double>();
+        product.SuppliersIndices = new List<int>();
+        Products.Add(product);
+        if (product.Potentials != null) Feedstocks.Add(product);
+        if (product.TransportTargts == null) {
+          product.Suppliers.Add(solution.LocationNames[locidx], 0);
+          product.SuppliersIndices.Add(locidx);
+        } else {
+          for (int i = 0; i < product.TransportTargts.Length; i++) {
+            if (product.TransportTargts[i] != locidx) continue;
+            var amount = 1d;
+            if (product.TransportedAmounts != null) {
+              amount = product.TransportedAmounts[i];
+            } else if (product.Potentials != null && product.Utilizations != null) {
+              amount = product.Potentials[i]*product.Utilizations[i];
+            }
+            if (amount > 0) {
+              product.SuppliersIndices.Add(i);
+              product.Suppliers.Add(solution.LocationNames[i], amount);
+            }
+          }
+        }
+      }
+    }
+
+    private static readonly Regex nameSplitter = new Regex(@"([^ ]+)( .*)");
+
+    private void AddProductInfo(Dictionary<string, ProductInfo> dict, string name, string suffix, Action<ProductInfo> setter) {
+      var match = nameSplitter.Match(name);
+      if (!match.Success) return;
+      if (!match.Groups[2].Success || match.Groups[2].Value != suffix) return;
+      var productName = match.Groups[1].Value;
+      ProductInfo info;
+      if (!dict.TryGetValue(productName, out info)) {
+        info = new ProductInfo { Name = productName };
+        dict.Add(productName, info);
+      }
+      setter(info);
+    }
+
+    private static DoubleArray Add(DoubleArray a, DoubleArray b) {
+      if (a == null) return b;
+      if (b == null) return a;
+      Debug.Assert(a.Length == b.Length);
+      var result = new DoubleArray(a.Length);
+      for (int i = 0; i < a.Length; i++) {
+        result[i] = a[i] + b[i];
+      }
+      return result;
+    }
+
+  }
+}
Index: /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/packages.config
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/packages.config	(revision 13072)
+++ /branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost.Views/3.3/packages.config	(revision 13072)
@@ -0,0 +1,13 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="BruTile" version="0.7.4.4" targetFramework="net45" />
+  <package id="Common.Logging" version="2.0.0" targetFramework="net45" />
+  <package id="GeoAPI" version="1.7.2" targetFramework="net45" />
+  <package id="NetTopologySuite" version="1.13.2" targetFramework="net45" />
+  <package id="NetTopologySuite.IO" version="1.13.2" targetFramework="net45" />
+  <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
+  <package id="ProjNET4GeoAPI" version="1.3.0.3" targetFramework="net45" />
+  <package id="SharpMap" version="1.1.0" targetFramework="net45" />
+  <package id="SharpMap.UI" version="1.1.0" targetFramework="net45" />
+  <package id="System.Data.SQLite.MSIL" version="1.0.86.0" targetFramework="net45" />
+</packages>
Index: /branches/HeuristicLab.Problems.BioBoost/packages/repositories.config
===================================================================
--- /branches/HeuristicLab.Problems.BioBoost/packages/repositories.config	(revision 13071)
+++ /branches/HeuristicLab.Problems.BioBoost/packages/repositories.config	(revision 13072)
@@ -1,4 +1,5 @@
 ﻿<?xml version="1.0" encoding="utf-8"?>
 <repositories>
+  <repository path="..\HeuristicLab.Problems.BioBoost.Views\3.3\packages.config" />
   <repository path="..\HeuristicLab.Problems.BioBoost\3.3\packages.config" />
 </repositories>
