Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChart.Designer.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChart.Designer.cs	(revision 13727)
+++ branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChart.Designer.cs	(revision 13727)
@@ -0,0 +1,58 @@
+﻿namespace HeuristicLab.VariableInteractionNetworks.Views {
+  partial class DirectedGraphChart {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DirectedGraphChart));
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // pictureBox
+      // 
+      this.pictureBox.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox.Image")));
+      // 
+      // toolTip
+      // 
+      this.toolTip.ShowAlways = true;
+      // 
+      // splitContainer
+      // 
+      // 
+      // DirectedGraphChart
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "DirectedGraphChart";
+      this.Controls.SetChildIndex(this.splitContainer, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+    #endregion
+  }
+}
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChart.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChart.cs	(revision 13727)
+++ branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChart.cs	(revision 13727)
@@ -0,0 +1,253 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Random;
+using HeuristicLab.Visualization;
+using Pen = System.Drawing.Pen;
+using Rectangle = HeuristicLab.Visualization.Rectangle;
+using Routing = HeuristicLab.VariableInteractionNetworks.Views.ConstrainedForceDirectedLayout.EdgeRouting;
+
+
+namespace HeuristicLab.VariableInteractionNetworks.Views {
+  public partial class DirectedGraphChart : ChartControl {
+    private ConstrainedForceDirectedLayout layout;
+    // provide direct and reverse mapping between graph objects and layout shapes
+    private Dictionary<IPrimitive, IVertex> vertexMap;
+    private Dictionary<IPrimitive, IArc> arcMap;
+    private Dictionary<IArc, LinearPrimitiveBase> arcShapes;
+    private Dictionary<IVertex, RectangularPrimitiveBase> vertexShapes;
+
+    // graph layout options
+    public double IdealEdgeLength { get; set; } = 50;
+    public bool PerformEdgeRouting { get; set; } = false;
+    public Routing RoutingMode { get; set; }
+
+    public IVertex GetVertex(IPrimitive primitive) {
+      IVertex v;
+      vertexMap.TryGetValue(primitive, out v);
+      return v;
+    }
+
+    public IArc GetArc(IPrimitive primitive) {
+      IArc a;
+      arcMap.TryGetValue(primitive, out a);
+      return a;
+    }
+
+    public RectangularPrimitiveBase GetVertexShape(IVertex v) {
+      RectangularPrimitiveBase p;
+      vertexShapes.TryGetValue(v, out p);
+      return p;
+    }
+
+    public LinearPrimitiveBase GetArcShape(IArc arc) {
+      LinearPrimitiveBase l;
+      arcShapes.TryGetValue(arc, out l);
+      return l;
+    }
+
+    public ToolTip ToolTip {
+      get { return toolTip; }
+    }
+
+    public DirectedGraphChart() {
+      InitializeComponent();
+
+      var directedGraphChartMode = new DirectedGraphChartMode(this);
+
+      this.AddChartModes(directedGraphChartMode, new PanChartMode(this), new ZoomInChartMode(this), new ZoomOutChartMode(this));
+      shapes = new Dictionary<Type, LabeledPrimitive>();
+    }
+
+    private IDirectedGraph graph;
+    public IDirectedGraph Graph {
+      get { return graph; }
+      set {
+        if (value == null || graph == value) return;
+        graph = value;
+        Draw();
+      }
+    }
+
+    private void RegisterEvents() { }
+
+    private void DeregisterEvents() { }
+
+    public void Draw() {
+      SuspendRendering();
+      Chart.Group.Clear();
+      vertexMap = new Dictionary<IPrimitive, IVertex>();
+      arcMap = new Dictionary<IPrimitive, IArc>();
+      var rng = new MersenneTwister();
+      vertexShapes = new Dictionary<IVertex, RectangularPrimitiveBase>();
+      arcShapes = new Dictionary<IArc, LinearPrimitiveBase>();
+      var vertexRectangles = new Dictionary<IVertex, RectangleF>();
+      foreach (var v in graph.Vertices) {
+        var shape = CreateShape(v);
+        vertexMap[shape] = v;
+        vertexShapes[v] = shape;
+        var width = (float)shape.Size.Width;
+        var height = (float)shape.Size.Height;
+        var x = (float)(rng.NextDouble() * (Chart.Size.Width - width));
+        var y = (float)(rng.NextDouble() * (Chart.Size.Height - height));
+        vertexRectangles[v] = new RectangleF(x, y, width, height);
+      }
+      layout = new ConstrainedForceDirectedLayout {
+        DefaultEdgeLength = IdealEdgeLength,
+        PerformEdgeRouting = PerformEdgeRouting,
+        LayoutWidth = (int)Chart.Size.Width,
+        LayoutHeight = (int)Chart.Size.Height,
+        MinHorizontalSpacing = 0,
+        MinVerticalSpacing = 0,
+        EdgeRoutingMode = RoutingMode
+      };
+
+      var arcs = graph.Vertices.SelectMany(x => x.InArcs).ToList();
+      if (arcs.Count != graph.Arcs.Count())
+        throw new Exception("Arcs count does not match!");
+
+      layout.Run(vertexRectangles);
+      var vertexPositions = layout.VertexPositions;
+      var arcRoutes = layout.ArcRoutes;
+
+      var max = arcRoutes.Keys.Max(x => x.Weight);
+
+      // move shapes to the positions computed by the layout
+      foreach (var pair in vertexPositions) {
+        var shape = vertexShapes[pair.Key];
+        var pos = vertexPositions[pair.Key];
+        shape.Move(new Offset(pos.X, pos.Y));
+      }
+
+      foreach (var pair in arcRoutes) {
+        var arc = pair.Key;
+        var weight = arc.Weight;
+        var points = pair.Value;
+        var target = (LabeledPrimitive)vertexShapes[pair.Key.Target];
+        var len = points.Length; // len = 2 when no edge routingMode is performed
+        Pen pen;
+        if (len == 2) {
+          pen = new Pen(Color.Black, (float)(weight / max * 3f)) { CustomEndCap = new AdjustableArrowCap(5, 3) };
+          var start = points[0];
+          var end = points[1];
+          var line = new Line(Chart, new PointD(start.X, start.Y), new PointD(end.X, end.Y));
+          var rect = target.Primitive as Rectangle;
+          var ell = target.Primitive as Ellipse;
+          PointD intersectionPoint;
+          if (rect != null)
+            intersectionPoint = rect.ComputeIntersect(line).FirstOrDefault();
+          else if (ell != null)
+            intersectionPoint = ell.ComputeIntersect(line).FirstOrDefault();
+          else
+            throw new InvalidOperationException("Unknown vertex shape.");
+          if (intersectionPoint == default(PointD))
+            intersectionPoint = end;
+          line = new Line(Chart, new PointD(start.X, start.Y), intersectionPoint, pen);
+          Chart.Group.Add(line);
+          arcShapes[arc] = line;
+          arcMap[line] = arc;
+        } else {
+          for (int i = 0; i < points.Length - 1; ++i) {
+            Line line;
+            var start = points[i];
+            var end = points[i + 1];
+
+            var segment = new Line(Chart, new PointD(start.X, start.Y), new PointD(end.X, end.Y));
+            var rect = target.Primitive as Rectangle;
+            var ell = target.Primitive as Ellipse;
+
+            PointD endPoint;
+            List<PointD> intersectionPoints;
+            if (rect != null) {
+              intersectionPoints = rect.ComputeIntersect(segment);
+            } else if (ell != null) {
+              intersectionPoints = ell.ComputeIntersect(segment);
+            } else {
+              throw new InvalidOperationException("Unknown vertex shape.");
+            }
+            if (intersectionPoints.Any()) {
+              endPoint = intersectionPoints.First();
+              pen = new Pen(Color.Black, (float)(weight / max * 3f)) { CustomEndCap = new AdjustableArrowCap(5, 3) };
+            } else {
+              endPoint = end;
+              pen = new Pen(Color.Black, (float)(weight / max * 3f));
+            }
+            line = new Line(Chart, new PointD(start.X, start.Y), endPoint, pen);
+            Chart.Group.Add(line);
+            if (intersectionPoints.Any()) {
+              arcShapes[arc] = line;
+              arcMap[line] = arc;
+              break;
+            }
+          }
+        }
+      }
+      // draw vertex shapes after the arcs so they appear on top
+      foreach (var pair in vertexPositions) {
+        var shape = vertexShapes[pair.Key];
+        shape.RedrawRequired += ShapeRedrawRequired;
+        Chart.Group.Add(shape);
+      }
+      ResumeRendering();
+    }
+
+    private void ShapeRedrawRequired(object sender, EventArgs args) {
+      layout.Run();
+    }
+
+    private Dictionary<Type, LabeledPrimitive> shapes;
+    public void AddShape(Type t, LabeledPrimitive shape) {
+      shapes[t] = shape;
+    }
+
+    public void ClearShapes() {
+      shapes.Clear();
+    }
+
+    private LabeledPrimitive CreateShape(IVertex v) {
+      var type = v.GetType();
+      if (!shapes.ContainsKey(type))
+        throw new ArgumentException(string.Format("No shape was associated with vertex type {0}", type));
+      var shape = shapes[type];
+      var p = shape.Primitive;
+      var rectangle = p as Rectangle;
+      var ellipse = p as Ellipse;
+      var brush = (SolidBrush)shape.Brush;
+
+      if (rectangle != null) {
+        var r = new Rectangle(this.Chart, shape.LowerLeft, shape.UpperRight, new Pen(shape.Pen.Color), new SolidBrush(brush.Color));
+        return new LabeledPrimitive(r, v.Label, shape.Font);
+      }
+      if (ellipse != null) {
+        var e = new Ellipse(this.Chart, shape.LowerLeft, shape.UpperRight, new Pen(shape.Pen.Color), new SolidBrush(brush.Color));
+        return new LabeledPrimitive(e, v.Label, shape.Font);
+      }
+      throw new Exception(string.Format("Unknown shape {0}.", shape));
+    }
+  }
+}
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChartMode.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChartMode.cs	(revision 13727)
+++ branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/DirectedGraphChartMode.cs	(revision 13727)
@@ -0,0 +1,130 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Visualization;
+
+namespace HeuristicLab.VariableInteractionNetworks.Views {
+  public class DirectedGraphChartMode : SelectChartMode {
+    public DirectedGraphChartMode(DirectedGraphChart control) : base(control) { }
+
+    public DirectedGraphChart Control {
+      get { return (DirectedGraphChart)chartControl; }
+    }
+
+    public override void HandleOnMouseDoubleClick(object sender, MouseEventArgs e) {
+      try {
+        switch (e.Button) {
+          case MouseButtons.Left:
+            try {
+              chartControl.SuspendRendering();
+              var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
+              foreach (var p in chartControl.Chart.Group.SelectedPrimitives.Where(x => !x.ContainsPoint(worldLocation)))
+                p.Selected = false;
+              var sp = chartControl.Chart.GetPrimitive(e.Location);
+              if (sp != null) sp.Selected = true;
+              if (sp is RectangularPrimitiveBase) {
+                var vertex = Control.GetVertex(sp) as IVertex<IDeepCloneable>;
+                if (vertex != null) {
+                  var content = vertex.Data as IContent;
+                  if (content != null) {
+                    MainFormManager.MainForm.ShowContent(content);
+                  }
+                }
+              }
+            } finally { chartControl.ResumeRendering(); }
+            break;
+        }
+      } finally {
+        base.HandleOnMouseDown(sender, e);
+      }
+    }
+
+    public override void HandleOnMouseMove(object sender, MouseEventArgs e) {
+      try {
+        switch (e.Button) {
+          case MouseButtons.None:
+            try {
+              chartControl.SuspendRendering();
+              var sp = chartControl.Chart.GetPrimitive(e.Location);
+              if (sp is RectangularPrimitiveBase) {
+                var vertex = Control.GetVertex(sp) as IVertex<IDeepCloneable>;
+                var junctionNode = vertex as JunctionNetworkNode;
+                if (junctionNode != null) {
+                  var solution = vertex.Data as IRegressionSolution;
+                  if (solution != null) {
+                    var toolTip = string.Format("Target: {0}\nQuality: {1}", solution.ProblemData.TargetVariable, solution.TrainingRSquared);
+                    Control.ToolTip.SetToolTip(Control, toolTip);
+                  }
+                }
+              }
+            } finally { chartControl.ResumeRendering(); }
+            break;
+          case MouseButtons.Left:
+            var previousWorldLocation = chartControl.Chart.TransformPixelToWorld(previousLocation);
+            var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
+            var offset = worldLocation - previousWorldLocation;
+            try {
+              chartControl.SuspendRendering();
+              foreach (var p in chartControl.Chart.Group.SelectedPrimitives.Where(p => p.ContainsPoint(previousWorldLocation))) {
+                var lp = p as LabeledPrimitive;
+                if (lp == null) continue;
+                p.Move(previousWorldLocation, offset);
+                var rect = lp.Primitive as Rectangle;
+                var ell = lp.Primitive as Ellipse;
+                if (rect == null && ell == null) continue;
+                var v = Control.GetVertex(p);
+                if (v == null) continue;
+                // ends of outgoing arcs need to be properly adjusted
+                foreach (var arc in v.InArcs) {
+                  var r = (LabeledPrimitive)Control.GetVertexShape(arc.Source);
+                  var line = (Line)Control.GetArcShape(arc);
+                  var tmp = new Line(this.chartControl.Chart, r.Primitive.Center(), lp.Primitive.Center());
+                  var intersect = rect == null ? ell.ComputeIntersect(tmp) : rect.ComputeIntersect(tmp);
+                  if (intersect.Any())
+                    line.SetPosition(tmp.Start, intersect.First());
+                }
+                foreach (var arc in v.OutArcs) {
+                  var r = (LabeledPrimitive)Control.GetVertexShape(arc.Target);
+                  rect = r.Primitive as Rectangle;
+                  ell = r.Primitive as Ellipse;
+                  var line = (Line)Control.GetArcShape(arc);
+                  var tmp = new Line(this.chartControl.Chart, lp.Primitive.Center(), r.Primitive.Center());
+                  var intersect = rect == null ? ell.ComputeIntersect(tmp) : rect.ComputeIntersect(tmp);
+                  if (intersect.Any())
+                    line.SetPosition(tmp.Start, intersect.First());
+                }
+              }
+            } finally { chartControl.ResumeRendering(); }
+            break;
+        }
+      } finally {
+        chartControl.UpdatePicture();
+        base.HandleOnMouseMove(sender, e);
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/HeuristicLab.VariableInteractionNetworks.Views-3.3.csproj
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/HeuristicLab.VariableInteractionNetworks.Views-3.3.csproj	(revision 13401)
+++ branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/HeuristicLab.VariableInteractionNetworks.Views-3.3.csproj	(revision 13727)
@@ -37,4 +37,12 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Cola, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\Cola.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -110,4 +118,12 @@
       <Private>False</Private>
     </Reference>
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Visualization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Visualization-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
@@ -127,11 +143,19 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="DirectedGraphChart.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DirectedGraphChart.Designer.cs">
+      <DependentUpon>DirectedGraphChart.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DirectedGraphChartMode.cs" />
+    <Compile Include="Layout\ConstrainedForceDirectedLayout.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="VariableInteractionNetworkView.cs">
+    <Compile Include="RunCollectionVariableInteractionNetworkView.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="VariableInteractionNetworkView.Designer.cs">
-      <DependentUpon>VariableInteractionNetworkView.cs</DependentUpon>
+    <Compile Include="RunCollectionVariableInteractionNetworkView.Designer.cs">
+      <DependentUpon>RunCollectionVariableInteractionNetworkView.cs</DependentUpon>
     </Compile>
   </ItemGroup>
@@ -146,9 +170,4 @@
     <None Include="HeuristicLab.snk" />
     <None Include="Plugin.cs.frame" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="VariableInteractionNetworkView.resx">
-      <DependentUpon>VariableInteractionNetworkView.cs</DependentUpon>
-    </EmbeddedResource>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/Layout/ConstrainedForceDirectedLayout.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/Layout/ConstrainedForceDirectedLayout.cs	(revision 13727)
+++ branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/Layout/ConstrainedForceDirectedLayout.cs	(revision 13727)
@@ -0,0 +1,295 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using Cola;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Random;
+using Point = Cola.Point;
+
+namespace HeuristicLab.VariableInteractionNetworks.Views {
+  public class ConstrainedForceDirectedLayout {
+    public enum EdgeRouting : uint {
+      None,
+      Polyline,
+      Orthogonal
+    }
+    private ConstrainedFDLayout layoutEngine;
+    private TopologyNodePtrs topologyNodes;
+    private TopologyEdgePtrs topologyRoutes;
+    private Cola.Doubles edgeLengths;
+    private int topologyNodeCount;
+    private readonly IRandom random = new MersenneTwister();
+    private Dictionary<uint, uint> idMap;
+    private Dictionary<IVertex, int> indexMap;
+    public double IdealEdgeLength { get; set; } = 1;
+    public double DefaultEdgeLength { get; set; } = 200;
+    public bool PreventOverlaps { get; set; } = true;
+    public int LayoutWidth { get; set; } = 800;
+    public int LayoutHeight { get; set; } = 600;
+    public bool PerformEdgeRouting { get; set; } = true;
+    public int MinHorizontalSpacing { get; set; } = 0;
+    public int MinVerticalSpacing { get; set; } = 0;
+    public EdgeRouting EdgeRoutingMode { get; set; } = EdgeRouting.None;
+
+    public Dictionary<IVertex, PointF> VertexPositions {
+      get {
+        var dict = new Dictionary<IVertex, PointF>();
+        foreach (var pair in indexMap) {
+          var node = topologyNodes[pair.Value];
+          var point = new PointF((float)node.rect.getMinX(), (float)node.rect.getMinY());
+          dict[pair.Key] = point;
+        }
+        return dict;
+      }
+    }
+
+    private List<IArc> arcs;
+    public Dictionary<IArc, PointF[]> ArcRoutes {
+      get {
+        var dict = new Dictionary<IArc, PointF[]>();
+        for (int i = 0; i < arcs.Count; ++i) {
+          var arc = arcs[i];
+          var route = topologyRoutes[i];
+          var vs = new TopologyEdgePointConstPtrs();
+          route.getPath(vs);
+          dict[arc] = vs.Select(x => new PointF((float)x.posX(), (float)x.posY())).ToArray();
+        }
+        return dict;
+      }
+    }
+
+    public ConstrainedForceDirectedLayout() { }
+
+    public void Run(Dictionary<IVertex, RectangleF> nodeShapes) {
+      if (nodeShapes.Count == 0) return;
+      indexMap = new Dictionary<IVertex, int>();
+      idMap = new Dictionary<uint, uint>();
+      var rectangles = new Cola.RectanglePtrs();
+      int i = 0;
+      arcs = new List<IArc>();
+      foreach (var pair in nodeShapes) {
+        var v = pair.Key;
+        arcs.AddRange(v.InArcs);
+        var p = pair.Value;
+
+        var width = p.Size.Width;
+        var height = p.Size.Height;
+
+        var x = random.NextDouble() * (LayoutWidth - width);
+        var y = random.NextDouble() * (LayoutHeight - height);
+        // randomize coordinates before passing them to the layout engine
+        var rect = new Cola.Rectangle(x, x + width, y, y + height);
+        rectangles.Add(rect);
+
+        indexMap[v] = i;
+        ++i;
+      }
+      topologyNodeCount = i;
+      var edges = new ColaEdges(arcs.Select(x => new ColaEdge((uint)indexMap[x.Source], (uint)indexMap[x.Target])).ToList());
+      edgeLengths = new Cola.Doubles(Enumerable.Range(0, edges.Count).Select(x => DefaultEdgeLength).ToList());
+
+      layoutEngine = new ConstrainedFDLayout(rectangles, edges, IdealEdgeLength, PreventOverlaps, edgeLengths);
+      var clusters = IdentifyClusters(rectangles, edges).ToList();
+      if (clusters.Count > 1) {
+        var rootCluster = new RootCluster();
+        foreach (var cluster in clusters) {
+          rootCluster.addChildCluster(cluster);
+        }
+        layoutEngine.setClusterHierarchy(rootCluster);
+      }
+      var ccs = new CompoundConstraintPtrs();
+      for (i = 0; i < rectangles.Count - 1; ++i) {
+        for (int j = i + 1; j < rectangles.Count; ++j) {
+          if (MinHorizontalSpacing > 0)
+            ccs.Add(new SeparationConstraint(Dim.XDIM, (uint)i, (uint)j, MinHorizontalSpacing, false));
+          if (MinVerticalSpacing > 0)
+            ccs.Add(new SeparationConstraint(Dim.YDIM, (uint)i, (uint)j, MinVerticalSpacing, false));
+        }
+      }
+      if (ccs.Any()) layoutEngine.setConstraints(ccs);
+      var topology = new ColaTopologyAddon();
+      layoutEngine.setTopology(topology);
+      layoutEngine.makeFeasible();
+      // store topology after makeFeasible()
+      topology = ColaTopologyAddon.CastToConcreteType(layoutEngine.getTopology());
+      layoutEngine.run();
+
+      topologyNodes = topology.topologyNodes;
+      topologyRoutes = topology.topologyRoutes;
+
+      if (PerformEdgeRouting) {
+        RouteEdges(edges);
+      } else {
+        int id = topologyNodeCount;
+        foreach (var edge in edges) {
+          var eps = new TopologyEdgePointPtrs();
+          var src = topologyNodes[(int)edge.first];
+          var dst = topologyNodes[(int)edge.second];
+          eps.Add(new EdgePoint(src, EdgePoint.RectIntersect.CENTRE));
+          eps.Add(new EdgePoint(dst, EdgePoint.RectIntersect.CENTRE));
+          topologyRoutes.Add(new Edge((uint)id++, IdealEdgeLength, eps));
+        }
+      }
+    }
+
+    private static void ColourNeighbours(IVertex v) {
+      foreach (var arc in v.InArcs) {
+        if (arc.Source.Weight > 0) continue;
+        arc.Source.Weight = v.Weight;
+        ColourNeighbours(arc.Source);
+      }
+      foreach (var arc in v.OutArcs) {
+        if (arc.Target.Weight > 0) continue;
+        arc.Target.Weight = v.Weight;
+        ColourNeighbours(arc.Target);
+      }
+    }
+
+    private static IEnumerable<Cluster> IdentifyClusters(RectanglePtrs rectangles, ColaEdges edges) {
+      var vertices = rectangles.Select(x => new Vertex()).ToList();
+      foreach (var e in edges) {
+        var i = (int)e.first;
+        var j = (int)e.second;
+        var arc = new Arc(vertices[i], vertices[j]);
+        vertices[i].AddArc(arc);
+        vertices[j].AddArc(arc);
+      }
+      while (vertices.Min(x => x.Weight).IsAlmost(0)) {
+        foreach (var v in vertices) {
+          if (v.Weight > 0) continue;
+          v.Weight = vertices.Max(x => x.Weight) + 1;
+          ColourNeighbours(v);
+        }
+      }
+      var colors = vertices.Select(x => (int)Math.Round(x.Weight)).ToList();
+      foreach (var i in colors.Distinct()) {
+        var cluster = new RectangularCluster();
+        for (int j = 0; j < colors.Count; ++j) {
+          if (colors[j] == i) cluster.addChildNode((uint)j);
+        }
+        yield return cluster;
+      }
+    }
+
+    private void RouteEdges(ColaEdges edges) {
+      // after the layout is done, we need to use a router to route edges
+      RouterFlag rf;
+      switch (EdgeRoutingMode) {
+        case EdgeRouting.Polyline:
+          rf = RouterFlag.PolyLineRouting;
+          break;
+        case EdgeRouting.Orthogonal:
+          rf = RouterFlag.OrthogonalRouting;
+          break;
+        default:
+          rf = RouterFlag.PolyLineRouting;
+          break;
+      }
+      var router = new Router((uint)rf);
+      router.setRoutingParameter(RoutingParameter.shapeBufferDistance, 5);
+      //router.setRoutingParameter(RoutingParameter.idealNudgingDistance, 0);
+      router.UseLeesAlgorithm = true;
+      router.InvisibilityGrph = false;
+      //router.RubberBandRouting = true;
+      var shapes = new List<ShapeRef>();
+      // consider topology routes only for the topologyNodes associated with our objects (the rectangles)
+
+      for (int i = 0; i < topologyNodeCount; ++i) {
+        var r = topologyNodes[i].rect;
+        var poly = new Polygon(4);
+        var xmin = r.getMinX();
+        var xmax = r.getMaxX();
+        var ymin = r.getMinY();
+        var ymax = r.getMaxY();
+
+        poly.ps[0] = new Cola.Point(xmax, ymin);
+        poly.ps[1] = new Cola.Point(xmax, ymax);
+        poly.ps[2] = new Cola.Point(xmin, ymax);
+        poly.ps[3] = new Cola.Point(xmin, ymin);
+        var shapeRef = new ShapeRef(router, poly);
+        idMap[shapeRef.id()] = (uint)i;
+        shapes.Add(shapeRef);
+      }
+      router.processTransaction();
+
+      var connRefs = new List<ConnRef>();
+      for (int i = 0; i < edges.Count; ++i) {
+        var edge = edges[i];
+        var src = topologyNodes[(int)edge.first];
+        var dst = topologyNodes[(int)edge.second];
+        var srcPt = new Cola.Point(src.rect.getCentreX(), src.rect.getCentreY());
+        var dstPt = new Cola.Point(dst.rect.getCentreX(), dst.rect.getCentreY());
+        var connRef = new ConnRef(router, new ConnEnd(srcPt), new ConnEnd(dstPt));
+        router.processTransaction();
+
+        //        var route = connRef.displayRoute().curvedPolyline(10);
+        var route = connRef.displayRoute();
+        var eps = new TopologyEdgePointPtrs(); // edge points
+        eps.Add(new EdgePoint(src, EdgePoint.RectIntersect.CENTRE));
+        for (int j = 1; j < route.size() - 1; ++j) {
+          var p = route.ps[j];
+          var ri = CalculateIntersect(p);
+          if (idMap.ContainsKey(p.id)) {
+            var node = topologyNodes[(int)idMap[p.id]];
+            eps.Add(new EdgePoint(node, ri));
+          } else {
+            // the node is not part of the topology and only represents a point in the route polyline
+            // therefore, we do not add it to the topologyNodes (although it may need to be treated separately in some cases)
+            var id = router.newObjectId();
+            var node = new Node(id, new Cola.Rectangle(p.x, p.x + 1, p.y, p.y + 1));
+            //topologyNodes.Add(node); 
+            idMap[id] = id;
+            eps.Add(new EdgePoint(node, ri));
+          }
+        }
+        eps.Add(new EdgePoint(dst, EdgePoint.RectIntersect.CENTRE));
+        topologyRoutes.Add(new Edge((uint)i, IdealEdgeLength, eps));
+        connRefs.Add(connRef);
+      }
+    }
+
+    public void Run() { }
+
+    public void UpdateNodePosition(IVertex v, PointF point) {
+      var node = topologyNodes[indexMap[v]];
+    }
+
+    private static EdgePoint.RectIntersect CalculateIntersect(Point p) {
+      switch (p.vn) {
+        case 0:
+          return EdgePoint.RectIntersect.BR;
+        case 1:
+          return EdgePoint.RectIntersect.TR;
+        case 2:
+          return EdgePoint.RectIntersect.TL;
+        case 3:
+          return EdgePoint.RectIntersect.BL;
+        default:
+          return EdgePoint.RectIntersect.CENTRE;
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.Designer.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.Designer.cs	(revision 13727)
+++ branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.Designer.cs	(revision 13727)
@@ -0,0 +1,272 @@
+﻿namespace HeuristicLab.VariableInteractionNetworks.Views {
+  partial class RunCollectionVariableInteractionNetworkView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+
+    #region Component Designer generated code
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.settingsGroupBox = new System.Windows.Forms.GroupBox();
+      this.impactThresholdTextBox = new System.Windows.Forms.TextBox();
+      this.impactAggregationComboBox = new System.Windows.Forms.ComboBox();
+      this.impactResultNameComboBox = new System.Windows.Forms.ComboBox();
+      this.weightAggregationLabel = new System.Windows.Forms.Label();
+      this.label2 = new System.Windows.Forms.Label();
+      this.label1 = new System.Windows.Forms.Label();
+      this.layoutOptionsGroupBox = new System.Windows.Forms.GroupBox();
+      this.idealEdgeLengthTextBox = new System.Windows.Forms.TextBox();
+      this.edgeRoutingComboBox = new System.Windows.Forms.ComboBox();
+      this.label4 = new System.Windows.Forms.Label();
+      this.label3 = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.qualityResultNameLabel = new System.Windows.Forms.Label();
+      this.qualityResultNameComboBox = new System.Windows.Forms.ComboBox();
+      this.maximizationCheckBox = new System.Windows.Forms.CheckBox();
+      this.graphChart = new HeuristicLab.VariableInteractionNetworks.Views.DirectedGraphChart();
+      this.settingsGroupBox.SuspendLayout();
+      this.layoutOptionsGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // settingsGroupBox
+      // 
+      this.settingsGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left)));
+      this.settingsGroupBox.Controls.Add(this.maximizationCheckBox);
+      this.settingsGroupBox.Controls.Add(this.qualityResultNameComboBox);
+      this.settingsGroupBox.Controls.Add(this.qualityResultNameLabel);
+      this.settingsGroupBox.Controls.Add(this.impactThresholdTextBox);
+      this.settingsGroupBox.Controls.Add(this.impactAggregationComboBox);
+      this.settingsGroupBox.Controls.Add(this.impactResultNameComboBox);
+      this.settingsGroupBox.Controls.Add(this.weightAggregationLabel);
+      this.settingsGroupBox.Controls.Add(this.label2);
+      this.settingsGroupBox.Controls.Add(this.label1);
+      this.settingsGroupBox.Location = new System.Drawing.Point(4, 4);
+      this.settingsGroupBox.Name = "settingsGroupBox";
+      this.settingsGroupBox.Size = new System.Drawing.Size(331, 230);
+      this.settingsGroupBox.TabIndex = 1;
+      this.settingsGroupBox.TabStop = false;
+      this.settingsGroupBox.Text = "Network Configuration";
+      // 
+      // impactThresholdTextBox
+      // 
+      this.impactThresholdTextBox.Location = new System.Drawing.Point(121, 94);
+      this.impactThresholdTextBox.Name = "impactThresholdTextBox";
+      this.impactThresholdTextBox.Size = new System.Drawing.Size(201, 20);
+      this.impactThresholdTextBox.TabIndex = 2;
+      this.impactThresholdTextBox.Text = "0.2";
+      this.impactThresholdTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.impactThresholdTextBox.Validated += new System.EventHandler(this.NetworkConfigurationBoxValidated);
+      // 
+      // impactAggregationComboBox
+      // 
+      this.impactAggregationComboBox.FormattingEnabled = true;
+      this.impactAggregationComboBox.Items.AddRange(new object[] {
+            "Best run",
+            "Runs average"});
+      this.impactAggregationComboBox.Location = new System.Drawing.Point(121, 120);
+      this.impactAggregationComboBox.Name = "impactAggregationComboBox";
+      this.impactAggregationComboBox.Size = new System.Drawing.Size(201, 21);
+      this.impactAggregationComboBox.TabIndex = 1;
+      this.impactAggregationComboBox.Text = "Best run";
+      this.impactAggregationComboBox.SelectedIndexChanged += new System.EventHandler(this.NetworkConfigurationChanged);
+      // 
+      // impactResultNameComboBox
+      // 
+      this.impactResultNameComboBox.FormattingEnabled = true;
+      this.impactResultNameComboBox.Location = new System.Drawing.Point(121, 67);
+      this.impactResultNameComboBox.Name = "impactResultNameComboBox";
+      this.impactResultNameComboBox.Size = new System.Drawing.Size(201, 21);
+      this.impactResultNameComboBox.TabIndex = 1;
+      this.impactResultNameComboBox.SelectedIndexChanged += new System.EventHandler(this.NetworkConfigurationChanged);
+      // 
+      // weightAggregationLabel
+      // 
+      this.weightAggregationLabel.AutoSize = true;
+      this.weightAggregationLabel.Location = new System.Drawing.Point(7, 123);
+      this.weightAggregationLabel.Name = "weightAggregationLabel";
+      this.weightAggregationLabel.Size = new System.Drawing.Size(98, 13);
+      this.weightAggregationLabel.TabIndex = 0;
+      this.weightAggregationLabel.Text = "Impact aggregation";
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(7, 97);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(85, 13);
+      this.label2.TabIndex = 0;
+      this.label2.Text = "Impact threshold";
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(7, 70);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(96, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "Impact result name";
+      // 
+      // layoutOptionsGroupBox
+      // 
+      this.layoutOptionsGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left)));
+      this.layoutOptionsGroupBox.Controls.Add(this.idealEdgeLengthTextBox);
+      this.layoutOptionsGroupBox.Controls.Add(this.edgeRoutingComboBox);
+      this.layoutOptionsGroupBox.Controls.Add(this.label4);
+      this.layoutOptionsGroupBox.Controls.Add(this.label3);
+      this.layoutOptionsGroupBox.Location = new System.Drawing.Point(4, 240);
+      this.layoutOptionsGroupBox.Name = "layoutOptionsGroupBox";
+      this.layoutOptionsGroupBox.Size = new System.Drawing.Size(331, 222);
+      this.layoutOptionsGroupBox.TabIndex = 2;
+      this.layoutOptionsGroupBox.TabStop = false;
+      this.layoutOptionsGroupBox.Text = "Layout Options";
+      // 
+      // idealEdgeLengthTextBox
+      // 
+      this.idealEdgeLengthTextBox.Location = new System.Drawing.Point(121, 43);
+      this.idealEdgeLengthTextBox.Name = "idealEdgeLengthTextBox";
+      this.idealEdgeLengthTextBox.Size = new System.Drawing.Size(201, 20);
+      this.idealEdgeLengthTextBox.TabIndex = 2;
+      this.idealEdgeLengthTextBox.Text = "50";
+      this.idealEdgeLengthTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
+      this.idealEdgeLengthTextBox.Validated += new System.EventHandler(this.LayoutConfigurationBoxValidated);
+      // 
+      // edgeRoutingComboBox
+      // 
+      this.edgeRoutingComboBox.FormattingEnabled = true;
+      this.edgeRoutingComboBox.Items.AddRange(new object[] {
+            "None",
+            "Polyline",
+            "Orthogonal"});
+      this.edgeRoutingComboBox.Location = new System.Drawing.Point(121, 17);
+      this.edgeRoutingComboBox.Name = "edgeRoutingComboBox";
+      this.edgeRoutingComboBox.Size = new System.Drawing.Size(201, 21);
+      this.edgeRoutingComboBox.TabIndex = 3;
+      this.edgeRoutingComboBox.Text = "None";
+      this.edgeRoutingComboBox.SelectedIndexChanged += new System.EventHandler(this.LayoutConfigurationChanged);
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(6, 46);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(89, 13);
+      this.label4.TabIndex = 0;
+      this.label4.Text = "Ideal edge length";
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(7, 20);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(67, 13);
+      this.label3.TabIndex = 0;
+      this.label3.Text = "Edge routing";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.ContainerControl = this;
+      // 
+      // qualityResultNameLabel
+      // 
+      this.qualityResultNameLabel.AutoSize = true;
+      this.qualityResultNameLabel.Location = new System.Drawing.Point(7, 20);
+      this.qualityResultNameLabel.Name = "qualityResultNameLabel";
+      this.qualityResultNameLabel.Size = new System.Drawing.Size(96, 13);
+      this.qualityResultNameLabel.TabIndex = 3;
+      this.qualityResultNameLabel.Text = "Quality result name";
+      // 
+      // qualityResultNameComboBox
+      // 
+      this.qualityResultNameComboBox.FormattingEnabled = true;
+      this.qualityResultNameComboBox.Location = new System.Drawing.Point(121, 17);
+      this.qualityResultNameComboBox.Name = "qualityResultNameComboBox";
+      this.qualityResultNameComboBox.Size = new System.Drawing.Size(201, 21);
+      this.qualityResultNameComboBox.TabIndex = 4;
+      this.qualityResultNameComboBox.SelectedIndexChanged += new System.EventHandler(this.NetworkConfigurationChanged);
+      // 
+      // maximizationCheckBox
+      // 
+      this.maximizationCheckBox.AutoSize = true;
+      this.maximizationCheckBox.Location = new System.Drawing.Point(236, 44);
+      this.maximizationCheckBox.Name = "maximizationCheckBox";
+      this.maximizationCheckBox.Size = new System.Drawing.Size(86, 17);
+      this.maximizationCheckBox.TabIndex = 5;
+      this.maximizationCheckBox.Text = "Maximization";
+      this.maximizationCheckBox.UseVisualStyleBackColor = true;
+      this.maximizationCheckBox.CheckedChanged += new System.EventHandler(this.NetworkConfigurationChanged);
+      // 
+      // graphChart
+      // 
+      this.graphChart.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.graphChart.BackColor = System.Drawing.SystemColors.Control;
+      this.graphChart.Graph = null;
+      this.graphChart.IdealEdgeLength = 50D;
+      this.graphChart.Location = new System.Drawing.Point(341, 4);
+      this.graphChart.Mode = null;
+      this.graphChart.Name = "graphChart";
+      this.graphChart.PerformEdgeRouting = false;
+      this.graphChart.RoutingMode = HeuristicLab.VariableInteractionNetworks.Views.ConstrainedForceDirectedLayout.EdgeRouting.None;
+      this.graphChart.ScaleOnResize = true;
+      this.graphChart.ShowToolBar = true;
+      this.graphChart.Size = new System.Drawing.Size(411, 458);
+      this.graphChart.TabIndex = 0;
+      // 
+      // RunCollectionVariableInteractionNetworkView
+      // 
+      this.Controls.Add(this.layoutOptionsGroupBox);
+      this.Controls.Add(this.settingsGroupBox);
+      this.Controls.Add(this.graphChart);
+      this.Name = "RunCollectionVariableInteractionNetworkView";
+      this.Size = new System.Drawing.Size(755, 465);
+      this.settingsGroupBox.ResumeLayout(false);
+      this.settingsGroupBox.PerformLayout();
+      this.layoutOptionsGroupBox.ResumeLayout(false);
+      this.layoutOptionsGroupBox.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private DirectedGraphChart graphChart;
+    private System.Windows.Forms.GroupBox settingsGroupBox;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.ComboBox impactResultNameComboBox;
+    private System.Windows.Forms.TextBox impactThresholdTextBox;
+    private System.Windows.Forms.GroupBox layoutOptionsGroupBox;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.ComboBox edgeRoutingComboBox;
+    private System.Windows.Forms.TextBox idealEdgeLengthTextBox;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.ComboBox impactAggregationComboBox;
+    private System.Windows.Forms.Label weightAggregationLabel;
+    private System.Windows.Forms.Label qualityResultNameLabel;
+    private System.Windows.Forms.ComboBox qualityResultNameComboBox;
+    private System.Windows.Forms.CheckBox maximizationCheckBox;
+  }
+}
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.cs	(revision 13727)
+++ branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.cs	(revision 13727)
@@ -0,0 +1,366 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Visualization;
+using Rectangle = HeuristicLab.Visualization.Rectangle;
+
+namespace HeuristicLab.VariableInteractionNetworks.Views {
+  [View("Variable Interaction Network")]
+  [Content(typeof(RunCollection), IsDefaultView = false)]
+
+  public sealed partial class RunCollectionVariableInteractionNetworkView : ItemView {
+    public RunCollectionVariableInteractionNetworkView() {
+      InitializeComponent();
+      ConfigureNodeShapes();
+    }
+
+    public new RunCollection Content {
+      get { return (RunCollection)base.Content; }
+      set {
+        if (value != null && value != Content) {
+          base.Content = value;
+        }
+      }
+    }
+
+    private static VariableInteractionNetwork BuildNetworkFromSolutionQualities(RunCollection runs, double threshold, bool useBestRunsPerTarget = false) {
+      var nodes = new Dictionary<string, IVertex>();
+      var vn = new VariableInteractionNetwork();
+      var targets = runs.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
+      var targetQualities = new Dictionary<string, double>();
+      var targetInputs = new Dictionary<string, List<string>>();
+
+      if (useBestRunsPerTarget) {
+        foreach (var target in targets) {
+          var bestRun = target.OrderBy(x => ((DoubleValue)x.Results["Best training solution quality"]).Value).First();
+          var bestQuality = ((DoubleValue)bestRun.Results["Best training solution quality"]).Value;
+          var pd = (IRegressionProblemData)bestRun.Parameters["ProblemData"];
+          if (threshold > bestQuality) continue; // skip if quality is below the treshold
+          targetQualities[target.Key] = bestQuality;
+          targetInputs[target.Key] = pd.AllowedInputVariables.ToList();
+        }
+      } else {
+        foreach (var target in targets) {
+          var avgQuality = CalculateAverageQuality(new RunCollection(target));
+          if (threshold > avgQuality) continue;
+          targetQualities[target.Key] = avgQuality;
+          var pd = (IRegressionProblemData)target.First().Parameters["ProblemData"];
+          targetInputs[target.Key] = pd.AllowedInputVariables.ToList();
+        }
+      }
+
+      foreach (var ti in targetQualities) {
+        var target = ti.Key;
+        var variables = targetInputs[ti.Key];
+        var quality = ti.Value;
+        IVertex targetNode;
+
+        if (!nodes.TryGetValue(target, out targetNode)) {
+          targetNode = new VariableNetworkNode { Label = target };
+          vn.AddVertex(targetNode);
+          nodes[target] = targetNode;
+        }
+
+        IVertex variableNode;
+        if (variables.Count > 0) {
+          var variableList = new List<string>(variables);
+          variableList.Add(target);
+          var junctionLabel = Concatenate(variableList);
+          IVertex junctionNode;
+          if (!nodes.TryGetValue(junctionLabel, out junctionNode)) {
+            junctionNode = new JunctionNetworkNode { Label = string.Empty };
+            vn.AddVertex(junctionNode);
+            nodes[junctionLabel] = junctionNode;
+          }
+          IArc arc;
+          foreach (var v in variables) {
+            var impact = quality;
+            if (!nodes.TryGetValue(v, out variableNode)) {
+              variableNode = new VariableNetworkNode { Label = v };
+              vn.AddVertex(variableNode);
+              nodes[v] = variableNode;
+            }
+            arc = new Arc(variableNode, junctionNode) { Weight = impact };
+            vn.AddArc(arc);
+          }
+          arc = new Arc(junctionNode, targetNode) { Weight = junctionNode.InArcs.Sum(x => x.Weight) };
+          vn.AddArc(arc);
+        } else {
+          foreach (var v in variables) {
+            var impact = quality;
+            if (!nodes.TryGetValue(v, out variableNode)) {
+              variableNode = new VariableNetworkNode { Label = v };
+              vn.AddVertex(variableNode);
+              nodes[v] = variableNode;
+            }
+            var arc = new Arc(variableNode, targetNode) { Weight = impact };
+            vn.AddArc(arc);
+          }
+        }
+      }
+
+      return vn;
+    }
+
+    private static VariableInteractionNetwork BuildNetworkFromVariableImpacts(RunCollection runs, string qualityResultName, bool maximization, string impactsResultName, double threshold, bool useBestRunsPerTarget = false) {
+      var nodes = new Dictionary<string, IVertex>();
+      var vn = new VariableInteractionNetwork();
+      var targets = runs.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
+
+      var targetImpacts = new Dictionary<string, Dictionary<string, double>>();
+
+      if (useBestRunsPerTarget) {
+        var bestRunsPerTarget = maximization ?
+          targets.Select(x => x.OrderBy(y => ((DoubleValue)y.Results[qualityResultName]).Value).Last()) :
+          targets.Select(x => x.OrderBy(y => ((DoubleValue)y.Results[qualityResultName]).Value).First());
+
+        foreach (var run in bestRunsPerTarget) {
+          var pd = (IRegressionProblemData)run.Parameters["ProblemData"];
+          var target = pd.TargetVariable;
+          var impacts = (DoubleMatrix)run.Results[impactsResultName];
+          targetImpacts[target] = impacts.RowNames.Select((x, i) => new { Name = x, Index = i }).ToDictionary(x => x.Name, x => impacts[x.Index, 0]);
+        }
+      } else {
+        foreach (var target in targets) {
+          var averageImpacts = CalculateAverageImpacts(new RunCollection(target), impactsResultName);
+          targetImpacts[target.Key] = averageImpacts;
+        }
+      }
+
+      foreach (var ti in targetImpacts) {
+        var target = ti.Key;
+        var variableImpacts = ti.Value;
+        IVertex targetNode;
+
+        var variables = variableImpacts.Keys.Where(x => variableImpacts[x] >= threshold).ToList();
+        if (variables.Count == 0) continue;
+
+        if (!nodes.TryGetValue(target, out targetNode)) {
+          targetNode = new VariableNetworkNode { Label = target };
+          vn.AddVertex(targetNode);
+          nodes[target] = targetNode;
+        }
+
+        IVertex variableNode;
+        if (variables.Count > 1) {
+          var variableList = new List<string>(variables) { target };
+          var junctionLabel = Concatenate(variableList);
+          IVertex junctionNode;
+          if (!nodes.TryGetValue(junctionLabel, out junctionNode)) {
+            junctionNode = new JunctionNetworkNode { Label = string.Empty };
+            vn.AddVertex(junctionNode);
+            nodes[junctionLabel] = junctionNode;
+          }
+          IArc arc;
+          foreach (var v in variables) {
+            var impact = variableImpacts[v];
+            if (!nodes.TryGetValue(v, out variableNode)) {
+              variableNode = new VariableNetworkNode { Label = v };
+              vn.AddVertex(variableNode);
+              nodes[v] = variableNode;
+            }
+            arc = new Arc(variableNode, junctionNode) { Weight = impact };
+            vn.AddArc(arc);
+          }
+          arc = new Arc(junctionNode, targetNode) { Weight = junctionNode.InArcs.Sum(x => x.Weight) };
+          vn.AddArc(arc);
+        } else {
+          foreach (var v in variables) {
+            var impact = variableImpacts[v];
+            if (!nodes.TryGetValue(v, out variableNode)) {
+              variableNode = new VariableNetworkNode { Label = v };
+              vn.AddVertex(variableNode);
+              nodes[v] = variableNode;
+            }
+            var arc = new Arc(variableNode, targetNode) { Weight = impact };
+            vn.AddArc(arc);
+          }
+        }
+      }
+      return vn;
+    }
+
+    private static double CalculateAverageQuality(RunCollection runs) {
+      var pd = (IRegressionProblemData)runs.First().Parameters["ProblemData"];
+      var target = pd.TargetVariable;
+      var inputs = pd.AllowedInputVariables;
+
+      if (!runs.All(x => {
+        var problemData = (IRegressionProblemData)x.Parameters["ProblemData"];
+        return target == problemData.TargetVariable && inputs.SequenceEqual(problemData.AllowedInputVariables);
+      })) {
+        throw new ArgumentException("All runs must have the same target and inputs.");
+      }
+      return runs.Average(x => ((DoubleValue)x.Results["Best training solution quality"]).Value);
+    }
+
+    private static Dictionary<string, double> CalculateAverageImpacts(RunCollection runs, string resultName) {
+      var pd = (IRegressionProblemData)runs.First().Parameters["ProblemData"];
+      var target = pd.TargetVariable;
+      var inputs = pd.AllowedInputVariables.ToList();
+
+      var impacts = inputs.ToDictionary(x => x, x => 0d);
+
+      // check if all the runs have the same target and same inputs
+      if (!runs.All(x => {
+        var problemData = (IRegressionProblemData)x.Parameters["ProblemData"];
+        return target == problemData.TargetVariable && inputs.SequenceEqual(problemData.AllowedInputVariables);
+      })) {
+        throw new ArgumentException("All runs must have the same target and inputs.");
+      }
+
+      foreach (var run in runs) {
+        var impactsMatrix = (DoubleMatrix)run.Results[resultName];
+
+        int i = 0;
+        foreach (var v in impactsMatrix.RowNames) {
+          impacts[v] += impactsMatrix[i, 0];
+          ++i;
+        }
+      }
+
+      foreach (var v in inputs) {
+        impacts[v] /= runs.Count;
+      }
+
+      return impacts;
+    }
+
+    private static string Concatenate(IEnumerable<string> strings) {
+      var sb = new StringBuilder();
+      foreach (var s in strings) {
+        sb.Append(s);
+      }
+      return sb.ToString();
+    }
+
+    private void ConfigureNodeShapes() {
+      graphChart.ClearShapes();
+      var font = new Font(FontFamily.GenericSansSerif, 12);
+      graphChart.AddShape(typeof(VariableNetworkNode), new LabeledPrimitive(new Ellipse(graphChart.Chart, new PointD(0, 0), new PointD(30, 30), Pens.Black, Brushes.White), "", font));
+      graphChart.AddShape(typeof(JunctionNetworkNode), new LabeledPrimitive(new Rectangle(graphChart.Chart, new PointD(0, 0), new PointD(15, 15), Pens.Black, Brushes.DarkGray), "", font));
+    }
+
+    #region events
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      var run = Content.First();
+      var pd = (IRegressionProblemData)run.Parameters["ProblemData"];
+      var variables = new HashSet<string>(new List<string>(pd.Dataset.DoubleVariables));
+      impactResultNameComboBox.Items.Clear();
+      foreach (var result in run.Results.Where(x => x.Value is DoubleMatrix)) {
+        var m = (DoubleMatrix)result.Value;
+        if (m.RowNames.All(x => variables.Contains(x)))
+          impactResultNameComboBox.Items.Add(result.Key);
+      }
+      qualityResultNameComboBox.Items.Clear();
+      foreach (var result in run.Results.Where(x => x.Value is DoubleValue)) {
+        qualityResultNameComboBox.Items.Add(result.Key);
+      }
+      if (impactResultNameComboBox.Items.Count > 0) {
+        impactResultNameComboBox.Text = (string)impactResultNameComboBox.Items[0];
+      }
+      if (qualityResultNameComboBox.Items.Count > 0) {
+        qualityResultNameComboBox.Text = (string)qualityResultNameComboBox.Items[0];
+      }
+      if (impactResultNameComboBox.Items.Count > 0 && qualityResultNameComboBox.Items.Count > 0)
+        NetworkConfigurationChanged(this, EventArgs.Empty);
+    }
+
+    private void TextBoxValidating(object sender, CancelEventArgs e) {
+      double v;
+      string errorMsg = "Could not parse the entered value. Please input a real number.";
+      var tb = (TextBox)sender;
+      if (!double.TryParse(tb.Text, out v)) {
+        e.Cancel = true;
+        tb.Select(0, tb.Text.Length);
+
+        // Set the ErrorProvider error with the text to display. 
+        this.errorProvider.SetError(tb, errorMsg);
+        errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;
+        errorProvider.SetIconPadding(tb, -20);
+      }
+    }
+
+    private void NetworkConfigurationBoxValidated(object sender, EventArgs e) {
+      var tb = (TextBox)sender;
+      errorProvider.SetError(tb, string.Empty);
+      NetworkConfigurationChanged(sender, e);
+    }
+
+    private void LayoutConfigurationBoxValidated(object sender, EventArgs e) {
+      var tb = (TextBox)sender;
+      errorProvider.SetError(tb, string.Empty);
+      LayoutConfigurationChanged(sender, e);
+    }
+
+    private void NetworkConfigurationChanged(object sender, EventArgs e) {
+      var useBest = impactAggregationComboBox.SelectedIndex <= 0;
+      var threshold = double.Parse(impactThresholdTextBox.Text);
+      var qualityResultName = qualityResultNameComboBox.Text;
+      var impactsResultName = impactResultNameComboBox.Text;
+      if (string.IsNullOrEmpty(qualityResultName) || string.IsNullOrEmpty(impactsResultName))
+        return;
+      var maximization = maximizationCheckBox.Checked;
+      var network = BuildNetworkFromVariableImpacts(Content, qualityResultName, maximization, impactsResultName, threshold, useBest);
+      if (network.Vertices.Any())
+        graphChart.Graph = network;
+    }
+
+    private void LayoutConfigurationChanged(object sender, EventArgs e) {
+      ConstrainedForceDirectedLayout.EdgeRouting routingMode;
+      switch (edgeRoutingComboBox.SelectedIndex) {
+        case 0:
+          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.None;
+          break;
+        case 1:
+          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.Polyline;
+          break;
+        case 2:
+          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.Orthogonal;
+          break;
+        default:
+          throw new ArgumentException("Invalid edge routing mode.");
+      }
+      var idealEdgeLength = double.Parse(idealEdgeLengthTextBox.Text);
+      if (routingMode == graphChart.RoutingMode && idealEdgeLength.IsAlmost(graphChart.IdealEdgeLength)) return;
+      graphChart.RoutingMode = routingMode;
+      graphChart.PerformEdgeRouting = routingMode != ConstrainedForceDirectedLayout.EdgeRouting.None;
+      graphChart.IdealEdgeLength = idealEdgeLength;
+      graphChart.Draw();
+    }
+    #endregion
+  }
+}
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/VariableInteractionNetworkView.Designer.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/VariableInteractionNetworkView.Designer.cs	(revision 13401)
+++ 	(revision )
@@ -1,336 +1,0 @@
-﻿using System.Linq;
-
-namespace HeuristicLab.VariableInteractionNetworks.Views
-{
-    partial class VariableInteractionNetworkView
-    {
-        /// <summary> 
-        /// Required designer variable.
-        /// </summary>
-        private System.ComponentModel.IContainer components = null;
-
-        /// <summary> 
-        /// Clean up any resources being used.
-        /// </summary>
-        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing && (components != null))
-            {
-                components.Dispose();
-            }
-            base.Dispose(disposing);
-        }
-
-
-        #region Component Designer generated code
-
-        /// <summary> 
-        /// Required method for Designer support - do not modify 
-        /// the contents of this method with the code editor.
-        /// </summary>
-        private void InitializeComponent()
-        {
-            this.components = new System.ComponentModel.Container();
-            this.groupBox1 = new System.Windows.Forms.GroupBox();
-            this.viewHost1 = new HeuristicLab.MainForm.WindowsForms.ViewHost();
-            this.viewHost2 = new HeuristicLab.MainForm.WindowsForms.ViewHost();
-            this.groupBox2 = new System.Windows.Forms.GroupBox();
-            this.viewHost3 = new HeuristicLab.MainForm.WindowsForms.ViewHost();
-            this.groupBox4 = new System.Windows.Forms.GroupBox();
-            this.textBox4 = new System.Windows.Forms.TextBox();
-            this.textBox3 = new System.Windows.Forms.TextBox();
-            this.selectTargetVariable = new System.Windows.Forms.Label();
-            this.targetVariablesCombo = new System.Windows.Forms.ComboBox();
-            this.selectedThreshold2 = new System.Windows.Forms.Label();
-            this.targetThreshold = new System.Windows.Forms.TextBox();
-            this.trackBar2 = new System.Windows.Forms.TrackBar();
-            this.groupBox3 = new System.Windows.Forms.GroupBox();
-            this.textBox2 = new System.Windows.Forms.TextBox();
-            this.textBox1 = new System.Windows.Forms.TextBox();
-            this.selectedThreshold1 = new System.Windows.Forms.Label();
-            this.genThreshold = new System.Windows.Forms.TextBox();
-            this.trackBar1 = new System.Windows.Forms.TrackBar();
-            this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
-            this.errorProvider2 = new System.Windows.Forms.ErrorProvider(this.components);
-            this.groupBox1.SuspendLayout();
-            this.groupBox2.SuspendLayout();
-            this.groupBox4.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.trackBar2)).BeginInit();
-            this.groupBox3.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
-            ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
-            ((System.ComponentModel.ISupportInitialize)(this.errorProvider2)).BeginInit();
-            this.SuspendLayout();
-            // 
-            // groupBox1
-            // 
-            this.groupBox1.Controls.Add(this.viewHost1);
-            this.groupBox1.Controls.Add(this.viewHost2);
-            this.groupBox1.Location = new System.Drawing.Point(6, 3);
-            this.groupBox1.Name = "groupBox1";
-            this.groupBox1.Size = new System.Drawing.Size(641, 276);
-            this.groupBox1.TabIndex = 0;
-            this.groupBox1.TabStop = false;
-            this.groupBox1.Text = "Adjacency Matrix. Node Impacts";
-            // 
-            // viewHost1
-            // 
-            this.viewHost1.Caption = "View";
-            this.viewHost1.Content = null;
-            this.viewHost1.Enabled = false;
-            this.viewHost1.Location = new System.Drawing.Point(6, 19);
-            this.viewHost1.Name = "viewHost1";
-            this.viewHost1.ReadOnly = false;
-            this.viewHost1.Size = new System.Drawing.Size(354, 247);
-            this.viewHost1.TabIndex = 0;
-            this.viewHost1.ViewsLabelVisible = true;
-            this.viewHost1.ViewType = null;
-            // 
-            // viewHost2
-            // 
-            this.viewHost2.Caption = "View";
-            this.viewHost2.Content = null;
-            this.viewHost2.Enabled = false;
-            this.viewHost2.Location = new System.Drawing.Point(365, 19);
-            this.viewHost2.Name = "viewHost2";
-            this.viewHost2.ReadOnly = false;
-            this.viewHost2.Size = new System.Drawing.Size(218, 247);
-            this.viewHost2.TabIndex = 0;
-            this.viewHost2.ViewsLabelVisible = true;
-            this.viewHost2.ViewType = null;
-            // 
-            // groupBox2
-            // 
-            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
-            | System.Windows.Forms.AnchorStyles.Left)));
-            this.groupBox2.Controls.Add(this.viewHost3);
-            this.groupBox2.Controls.Add(this.groupBox4);
-            this.groupBox2.Controls.Add(this.groupBox3);
-            this.groupBox2.Location = new System.Drawing.Point(6, 285);
-            this.groupBox2.Name = "groupBox2";
-            this.groupBox2.Size = new System.Drawing.Size(641, 283);
-            this.groupBox2.TabIndex = 1;
-            this.groupBox2.TabStop = false;
-            this.groupBox2.Text = "Updated Adjacency Matrix";
-            // 
-            // viewHost3
-            // 
-            this.viewHost3.Caption = "View";
-            this.viewHost3.Content = null;
-            this.viewHost3.Enabled = false;
-            this.viewHost3.Location = new System.Drawing.Point(6, 19);
-            this.viewHost3.Name = "viewHost3";
-            this.viewHost3.ReadOnly = false;
-            this.viewHost3.Size = new System.Drawing.Size(354, 239);
-            this.viewHost3.TabIndex = 0;
-            this.viewHost3.ViewsLabelVisible = true;
-            this.viewHost3.ViewType = null;
-            // 
-            // groupBox4
-            // 
-            this.groupBox4.Controls.Add(this.textBox4);
-            this.groupBox4.Controls.Add(this.textBox3);
-            this.groupBox4.Controls.Add(this.selectTargetVariable);
-            this.groupBox4.Controls.Add(this.targetVariablesCombo);
-            this.groupBox4.Controls.Add(this.selectedThreshold2);
-            this.groupBox4.Controls.Add(this.targetThreshold);
-            this.groupBox4.Controls.Add(this.trackBar2);
-            this.groupBox4.Location = new System.Drawing.Point(365, 148);
-            this.groupBox4.Name = "groupBox4";
-            this.groupBox4.Size = new System.Drawing.Size(255, 123);
-            this.groupBox4.TabIndex = 13;
-            this.groupBox4.TabStop = false;
-            this.groupBox4.Text = "Apply Edge Weights Threshold for a Chosen Target Variable";
-            // 
-            // textBox4
-            // 
-            this.textBox4.BackColor = System.Drawing.SystemColors.Control;
-            this.textBox4.Location = new System.Drawing.Point(217, 60);
-            this.textBox4.Name = "textBox4";
-            this.textBox4.ReadOnly = true;
-            this.textBox4.Size = new System.Drawing.Size(32, 20);
-            this.textBox4.TabIndex = 14;
-            // 
-            // textBox3
-            // 
-            this.textBox3.BackColor = System.Drawing.SystemColors.Control;
-            this.textBox3.Location = new System.Drawing.Point(6, 60);
-            this.textBox3.Name = "textBox3";
-            this.textBox3.ReadOnly = true;
-            this.textBox3.Size = new System.Drawing.Size(33, 20);
-            this.textBox3.TabIndex = 14;
-            // 
-            // selectTargetVariable
-            // 
-            this.selectTargetVariable.AutoSize = true;
-            this.selectTargetVariable.Location = new System.Drawing.Point(31, 36);
-            this.selectTargetVariable.Name = "selectTargetVariable";
-            this.selectTargetVariable.Size = new System.Drawing.Size(112, 13);
-            this.selectTargetVariable.TabIndex = 8;
-            this.selectTargetVariable.Text = "Select Target Variable";
-            // 
-            // targetVariablesCombo
-            // 
-            this.targetVariablesCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-            this.targetVariablesCombo.FormattingEnabled = true;
-            this.targetVariablesCombo.Location = new System.Drawing.Point(159, 33);
-            this.targetVariablesCombo.Name = "targetVariablesCombo";
-            this.targetVariablesCombo.Size = new System.Drawing.Size(61, 21);
-            this.targetVariablesCombo.TabIndex = 1;
-            this.targetVariablesCombo.DropDown += new System.EventHandler(this.targetVariablesCombo_Dropdown);
-            this.targetVariablesCombo.SelectedIndexChanged += new System.EventHandler(this.targetVariablesCombo_SelectedIndexChanged);
-            // 
-            // selectedThreshold2
-            // 
-            this.selectedThreshold2.AutoSize = true;
-            this.selectedThreshold2.Location = new System.Drawing.Point(31, 93);
-            this.selectedThreshold2.Name = "selectedThreshold2";
-            this.selectedThreshold2.Size = new System.Drawing.Size(93, 13);
-            this.selectedThreshold2.TabIndex = 7;
-            this.selectedThreshold2.Text = "Select Threshold: ";
-            // 
-            // targetThreshold
-            // 
-            this.targetThreshold.Location = new System.Drawing.Point(132, 90);
-            this.targetThreshold.Name = "targetThreshold";
-            this.targetThreshold.Size = new System.Drawing.Size(48, 20);
-            this.targetThreshold.TabIndex = 6;
-            this.targetThreshold.Text = "0";
-            this.targetThreshold.TextChanged += new System.EventHandler(this.targetThreshold_TextChanged);
-            this.targetThreshold.KeyDown += new System.Windows.Forms.KeyEventHandler(this.targetThreshold_KeyDown);
-            // 
-            // trackBar2
-            // 
-            this.trackBar2.BackColor = System.Drawing.SystemColors.Control;
-            this.trackBar2.Cursor = System.Windows.Forms.Cursors.Hand;
-            this.trackBar2.LargeChange = 4;
-            this.trackBar2.Location = new System.Drawing.Point(34, 60);
-            this.trackBar2.Name = "trackBar2";
-            this.trackBar2.Size = new System.Drawing.Size(186, 45);
-            this.trackBar2.TabIndex = 3;
-            this.trackBar2.TickStyle = System.Windows.Forms.TickStyle.None;
-            this.trackBar2.ValueChanged += new System.EventHandler(this.trackBar2_ValueChanged);
-            this.trackBar2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.trackBar2_MouseDown);
-            // 
-            // groupBox3
-            // 
-            this.groupBox3.Controls.Add(this.textBox2);
-            this.groupBox3.Controls.Add(this.textBox1);
-            this.groupBox3.Controls.Add(this.selectedThreshold1);
-            this.groupBox3.Controls.Add(this.genThreshold);
-            this.groupBox3.Controls.Add(this.trackBar1);
-            this.groupBox3.Location = new System.Drawing.Point(365, 19);
-            this.groupBox3.Name = "groupBox3";
-            this.groupBox3.Size = new System.Drawing.Size(255, 95);
-            this.groupBox3.TabIndex = 12;
-            this.groupBox3.TabStop = false;
-            this.groupBox3.Text = "Apply General Threshold for Edge Weights";
-            // 
-            // textBox2
-            // 
-            this.textBox2.BackColor = System.Drawing.SystemColors.Control;
-            this.textBox2.Location = new System.Drawing.Point(217, 24);
-            this.textBox2.Name = "textBox2";
-            this.textBox2.ReadOnly = true;
-            this.textBox2.Size = new System.Drawing.Size(32, 20);
-            this.textBox2.TabIndex = 13;
-            // 
-            // textBox1
-            // 
-            this.textBox1.BackColor = System.Drawing.SystemColors.Control;
-            this.textBox1.Location = new System.Drawing.Point(6, 24);
-            this.textBox1.Name = "textBox1";
-            this.textBox1.ReadOnly = true;
-            this.textBox1.Size = new System.Drawing.Size(33, 20);
-            this.textBox1.TabIndex = 12;
-            // 
-            // selectedThreshold1
-            // 
-            this.selectedThreshold1.AutoSize = true;
-            this.selectedThreshold1.Location = new System.Drawing.Point(31, 62);
-            this.selectedThreshold1.Name = "selectedThreshold1";
-            this.selectedThreshold1.Size = new System.Drawing.Size(93, 13);
-            this.selectedThreshold1.TabIndex = 10;
-            this.selectedThreshold1.Text = "Select Threshold: ";
-            // 
-            // genThreshold
-            // 
-            this.genThreshold.Location = new System.Drawing.Point(132, 59);
-            this.genThreshold.Name = "genThreshold";
-            this.genThreshold.Size = new System.Drawing.Size(48, 20);
-            this.genThreshold.TabIndex = 9;
-            this.genThreshold.Text = "0";
-            this.genThreshold.TextChanged += new System.EventHandler(this.genThreshold_TextChanged);
-            this.genThreshold.KeyDown += new System.Windows.Forms.KeyEventHandler(this.genThreshold_KeyDown);
-            // 
-            // trackBar1
-            // 
-            this.trackBar1.Cursor = System.Windows.Forms.Cursors.Hand;
-            this.trackBar1.LargeChange = 4;
-            this.trackBar1.Location = new System.Drawing.Point(34, 24);
-            this.trackBar1.Name = "trackBar1";
-            this.trackBar1.RightToLeft = System.Windows.Forms.RightToLeft.No;
-            this.trackBar1.Size = new System.Drawing.Size(186, 45);
-            this.trackBar1.TabIndex = 2;
-            this.trackBar1.TickStyle = System.Windows.Forms.TickStyle.None;
-            this.trackBar1.ValueChanged += new System.EventHandler(this.trackBar1_ValueChanged);
-            this.trackBar1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.trackBar1_MouseDown);
-            // 
-            // errorProvider
-            // 
-            this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
-            this.errorProvider.ContainerControl = this;
-            // 
-            // errorProvider2
-            // 
-            this.errorProvider2.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
-            this.errorProvider2.ContainerControl = this;
-            // 
-            // VariableInteractionNetworkView
-            // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.Controls.Add(this.groupBox2);
-            this.Controls.Add(this.groupBox1);
-            this.Name = "VariableInteractionNetworkView";
-            this.Size = new System.Drawing.Size(810, 599);
-            this.groupBox1.ResumeLayout(false);
-            this.groupBox2.ResumeLayout(false);
-            this.groupBox4.ResumeLayout(false);
-            this.groupBox4.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.trackBar2)).EndInit();
-            this.groupBox3.ResumeLayout(false);
-            this.groupBox3.PerformLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
-            ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
-            ((System.ComponentModel.ISupportInitialize)(this.errorProvider2)).EndInit();
-            this.ResumeLayout(false);
-
-        }
-
-        #endregion
-
-        private System.Windows.Forms.GroupBox groupBox1;
-        private System.Windows.Forms.GroupBox groupBox2;
-        private System.Windows.Forms.GroupBox groupBox3;
-        private System.Windows.Forms.GroupBox groupBox4;
-        private MainForm.WindowsForms.ViewHost viewHost1;
-        private MainForm.WindowsForms.ViewHost viewHost2;
-        private MainForm.WindowsForms.ViewHost viewHost3;
-        private System.Windows.Forms.TrackBar trackBar1;
-        private System.Windows.Forms.TrackBar trackBar2;
-        private System.Windows.Forms.ComboBox targetVariablesCombo;
-        private System.Windows.Forms.TextBox genThreshold;
-        private System.Windows.Forms.TextBox targetThreshold;
-        private System.Windows.Forms.Label selectedThreshold2;
-        private System.Windows.Forms.Label selectedThreshold1;
-        private System.Windows.Forms.Label selectTargetVariable;
-        private System.Windows.Forms.TextBox textBox2;
-        private System.Windows.Forms.TextBox textBox1;
-        private System.Windows.Forms.ErrorProvider errorProvider;
-        private System.Windows.Forms.TextBox textBox4;
-        private System.Windows.Forms.TextBox textBox3;
-        private System.Windows.Forms.ErrorProvider errorProvider2;
-    }
-}
Index: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/VariableInteractionNetworkView.cs
===================================================================
--- branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/VariableInteractionNetworkView.cs	(revision 13401)
+++ 	(revision )
@@ -1,524 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Linq;
-using System.Windows.Forms;
-using HeuristicLab.Common;
-using HeuristicLab.Data;
-using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
-using HeuristicLab.Optimization;
-using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
-using System.Collections;
-
-namespace HeuristicLab.VariableInteractionNetworks.Views
-{
-    [View("Variable Interaction Network")]
-    [Content(typeof(RunCollection), IsDefaultView = false)]
-
-    public sealed partial class VariableInteractionNetworkView : AsynchronousContentView
-    {
-        private const string variableImpactResultName = "Variable impacts";
-        private const string TrainingBestSolutionParameterName = "Best training solution";
-
-        public new RunCollection Content
-        {
-            get { return (RunCollection)base.Content; }
-            set { base.Content = value; }
-        }
-
-        public VariableInteractionNetworkView()
-        {
-            InitializeComponent();
-        }
-
-        internal class NoFocusTrackBar : System.Windows.Forms.TrackBar
-        {
-            [System.Runtime.InteropServices.DllImport("user32.dll")]
-            public extern static int SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
-
-            private static int MakeParam(int loWord, int hiWord)
-            {
-                return (hiWord << 16) | (loWord & 0xffff);
-            }
-
-            protected override void OnGotFocus(EventArgs e)
-            {
-                base.OnGotFocus(e);
-                SendMessage(this.Handle, 0x0128, MakeParam(1, 0x1), 0);
-            }
-        }
-
-        #region events
-
-        //  #region Event Handlers (Content)
-        protected override void OnContentChanged()
-        {
-            base.OnContentChanged();
-            if (Content == null)
-            {
-                // TODO: Add code when content has been changed and is null
-            }
-            else
-            {
-                // TODO: Add code when content has been changed and is not null
-                viewHost2.Content = CalculateNodeImportance(CalculateAdjacencyMatrix());
-                var adjMatrix = CalculateAdjacencyMatrix();
-                viewHost1.Content = adjMatrix;
-                viewHost3.Content = (DoubleMatrix)adjMatrix.Clone();
-                trackBar1.Minimum = (int)(1000 * GetMinNonNullElement(adjMatrix));
-                trackBar1.Maximum = (int)(1000 * (adjMatrix.Max()));
-            }
-        }
-        #endregion
-
-        protected override void SetEnabledStateOfControls()
-        {
-            base.SetEnabledStateOfControls();
-            // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
-        }
-
-        #region Event Handlers (child controls)
-        // TODO: Put event handlers of child controls here.
-        #endregion
-
-        private DoubleMatrix CalculateAdjacencyMatrix()
-        {
-            var runCollection = Content;
-            var inputVariables = ((IRegressionProblemData)runCollection.First().Parameters["ProblemData"]).InputVariables.Select(x => x.Value).ToList();
-            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).OrderBy(x => inputVariables.IndexOf(x.Key)).ToList();
-
-            var allVariableImpacts = runCollection.Select(run => (DoubleMatrix)run.Results[variableImpactResultName]);
-            var variableNames = (from variableImpact in allVariableImpacts
-                                 from variableName in variableImpact.RowNames
-                                 select variableName).Distinct().ToArray();
-           
-            var vars = new List<Tuple<int, string>>();
-            
-            var allowedInputs = ((IRegressionProblemData)groupRunCollection[0].First().Parameters["ProblemData"]).AllowedInputVariables.ToList();
-
-            var adjMatrix = new DoubleMatrix(variableNames.Length, variableNames.Length);
-
-            for (int i = 0; i < adjMatrix.Rows; ++i)
-            {
-                int inputIndex = allowedInputs.FindIndex(x => x == variableNames[i]);
-                vars.Add(new Tuple<int, string>(inputIndex, variableNames[i]));
-            }
-
-            vars.Sort((a, b) => a.Item1.CompareTo(b.Item1));
-
-            for (int i = 0; i < adjMatrix.Rows; ++i)
-            {
-                variableNames[i] = vars[i].Item2;
-            }
-            adjMatrix.RowNames = variableNames;
-            adjMatrix.ColumnNames = adjMatrix.RowNames;
-
-            for (int j = 0; j < groupRunCollection.Count; ++j)
-            {
-                var g = groupRunCollection[j];
-                
-                var matrix = CalculateAdjacencyRows(g);
-                var variables = new List<double>();
-
-                for (int i = 0; i < matrix.Columns; ++i)
-                {
-                    variables.Add(matrix[0, i]);
-                }
-                
-                for (int i = 0; i < variables.Count; ++i)
-                {
-                    if (i == j)
-                    {
-                        adjMatrix[i, i] = 0;
-                        variables.Insert(i, 0);
-                    }
-                    else
-                        adjMatrix[j, i] = variables[i];
-                }
-            }
-            return adjMatrix;
-        }
-
-        private DoubleMatrix CalculateAdjacencyRows(IEnumerable<IRun> runs)
-        {
-            var runNames = runs.Select(x => x.Name).ToArray();
-            var runsArray = runs.ToArray();
-            DoubleMatrix varImpactMatrix = CalculateVariableImpactMatrix(runsArray, runNames);
-          
-            var targetMatrix = new DoubleMatrix(1, varImpactMatrix.Rows);
-
-            for (int i = 0; i < varImpactMatrix.Rows; ++i)
-            {
-                targetMatrix[0, i] = varImpactMatrix[i, runNames.Length];
-            }
-
-            targetMatrix.RowNames = new[] { "Impacts" };
-            targetMatrix.ColumnNames = varImpactMatrix.RowNames;
-            return targetMatrix;
-        }
-
-        private DoubleMatrix UpdateAdjacencyMatrixByThresholdAndTargetVariable(double threshold, string targetVariable, DoubleMatrix adjMatrix)
-        {
-            var originalMatrix = (DoubleMatrix)viewHost1.Content;
-            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
-            string[] targets = adjMatrix.RowNames.ToArray();
-            var targetIndex = Array.IndexOf(targets, targetVariable);
-
-            for (int j = 0; j < groupRunCollection.Count; ++j)
-            {
-                double originalValue = originalMatrix[targetIndex, j];
-                adjMatrix[targetIndex, j] = (originalValue <= Math.Max(threshold, Double.Parse(genThreshold.Text))) ? 0 : originalValue;
-            }
-            return adjMatrix;
-        }
-
-        private DoubleMatrix UpdateAdjacencyMatrixByThreshold(double threshold, DoubleMatrix adjMatrix)
-        {
-            var originalMatrix = (DoubleMatrix)viewHost1.Content;
-            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
-
-            for (int i = 0; i < adjMatrix.Rows; ++i)
-            {
-                for (int j = 0; j < adjMatrix.Columns; ++j)
-                {
-                    double originalValue = originalMatrix[i, j];
-                    adjMatrix[i, j] = originalValue <= threshold ? 0 : originalValue;
-                }
-            }
-            return adjMatrix;
-        }
-
-        private double GetMinNonNullElement(DoubleMatrix adjMatrix)
-        {
-            double min = adjMatrix.Max();
-            for (int i = 0; i < adjMatrix.Rows; i++)
-            {
-                for (int j = 0; j < adjMatrix.Columns; j++)
-                {                  
-                    min = (min > adjMatrix[i, j] && adjMatrix[i, j] != 0) ? adjMatrix[i, j] : min;
-                }
-            }
-            return min;
-        }
-
-        private double GetMaxFromRow(int rowIndex, DoubleMatrix adjMatrix)
-        {
-            double max = adjMatrix.Min();
-            for (int j = 0; j < adjMatrix.Columns; ++j)
-            {
-                max = (max < adjMatrix[rowIndex, j] && adjMatrix[rowIndex, j] != 0) ? adjMatrix[rowIndex, j] : max;
-            }
-            return max;
-        }
-
-        private DoubleMatrix CalculateNodeImportance(DoubleMatrix adjMatrix)
-        {
-            DoubleMatrix nodeImportance = new DoubleMatrix(adjMatrix.Rows, 1);
-            var variables = new List<Tuple<string, double>>();
-            var rowNames = adjMatrix.RowNames.ToList();
-            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
-            double[] meanQuality = new double[groupRunCollection.Count];
-
-            for (int j = 0; j < groupRunCollection.Count; ++j)
-            {
-                var g = groupRunCollection[j];
-                meanQuality[j] = g.Average(x => ((IRegressionSolution)x.Results[TrainingBestSolutionParameterName]).TrainingRSquared);
-            }
-
-            for (int i = 0; i < adjMatrix.Columns; ++i)
-            {
-                for (int j = 0; j < adjMatrix.Rows; ++j)
-                {
-                    nodeImportance[i, 0] += adjMatrix[j, i] * meanQuality[j];
-                }
-                nodeImportance[i, 0] /= (adjMatrix.Rows - 1);
-                variables.Add(new Tuple<string, double>(rowNames[i], nodeImportance[i, 0]));
-            }
-
-            variables.Sort((b, a) => a.Item2.CompareTo(b.Item2));
-
-            for (int i = 0; i < nodeImportance.Rows; ++i)
-            {
-                nodeImportance[i, 0] = variables[i].Item2;
-                rowNames[i] = variables[i].Item1;
-            }
-
-            nodeImportance.RowNames = rowNames;
-            nodeImportance.ColumnNames = new[] { "Node Importance" };
-            return nodeImportance;
-        }
-
-        //modified from RunCollectionVariableImpactView
-        private DoubleMatrix CalculateVariableImpactMatrix(IRun[] runs, string[] runNames)
-        {
-            IEnumerable<DoubleMatrix> allVariableImpacts = (from run in runs
-                                                            select run.Results[variableImpactResultName]).Cast<DoubleMatrix>();
-            IEnumerable<string> variableNames = (from variableImpact in allVariableImpacts
-                                                 from variableName in variableImpact.RowNames
-                                                 select variableName).Distinct();
-
-            // filter variableNames: only include names that have at least one non-zero value in a run
-            List<string> variableNamesList = (from variableName in variableNames
-                                              where GetVariableImpacts(variableName, allVariableImpacts).Any(x => !x.IsAlmost(0.0))
-                                              select variableName).ToList();
-
-            List<string> columnNames = new List<string>(runNames);
-            columnNames.Add("Mean");
-
-            int numberOfRuns = runs.Length;
-
-            DoubleMatrix matrix = new DoubleMatrix(variableNamesList.Count, numberOfRuns + 1);
-            matrix.SortableView = true;
-            matrix.ColumnNames = columnNames;
-
-            List<List<double>> variableImpactsOverRuns = (from variableName in variableNamesList
-                                                          select GetVariableImpacts(variableName, allVariableImpacts).ToList()).ToList();
-
-            for (int row = 0; row < variableImpactsOverRuns.Count; row++)
-            {
-                matrix[row, numberOfRuns] = Math.Round(variableImpactsOverRuns[row].Average(), 3);
-            }
-
-            // fill matrix with impacts from runs
-            for (int i = 0; i < runs.Length; i++)
-            {
-                IRun run = runs[i];
-                DoubleMatrix runVariableImpacts = (DoubleMatrix)run.Results[variableImpactResultName];
-                for (int j = 0; j < runVariableImpacts.Rows; j++)
-                {
-                    int rowIndex = variableNamesList.FindIndex(s => s == runVariableImpacts.RowNames.ElementAt(j));
-                    if (rowIndex > -1)
-                    {
-                        matrix[rowIndex, i] = Math.Round(runVariableImpacts[j, 0], 3);
-                    }
-                }
-            }
-
-            // sort by median
-            var sortedMatrix = (DoubleMatrix)matrix.Clone();
-            var sortedIndexes = from i in Enumerable.Range(0, sortedMatrix.Rows)
-                                orderby matrix[i, numberOfRuns]
-                                select i;
-
-            int targetIndex = 0;
-            foreach (var sourceIndex in sortedIndexes)
-            {
-                for (int c = 0; c < matrix.Columns; c++)
-                    sortedMatrix[targetIndex, c] = matrix[sourceIndex, c];
-                targetIndex++;
-            }
-            sortedMatrix.RowNames = sortedIndexes.Select(i => variableNamesList[i]);
-
-            var vars = new List<Tuple<int, string, double>>();
-            var rowNames = sortedMatrix.RowNames.ToList();
-
-            var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
-            var inputs = ((IRegressionProblemData)groupRunCollection[0].First().Parameters["ProblemData"]).InputVariables.ToList();
-            List<string> inp = (from input in inputs 
-                                select (input.ToString())).ToList();
-
-            for (int i = 0; i < sortedMatrix.Rows; ++i)
-            {
-                int inputIndex = inp.FindIndex(x => x == rowNames[i]);
-                vars.Add(new Tuple<int, string, double>(inputIndex, rowNames[i], sortedMatrix[i, runNames.Length]));
-            }
-
-                vars.Sort((a, b) => a.Item1.CompareTo(b.Item1));
-               
-            for (int i = 0; i < sortedMatrix.Rows; ++i)
-            {
-                sortedMatrix[i, runNames.Length] = vars[i].Item3;
-                rowNames[i] = vars[i].Item2;
-            }
-            sortedMatrix.RowNames = rowNames;
-
-            return sortedMatrix;
-        }
-
-        //taken from RunCollectionVariableImpactView
-        private IEnumerable<double> GetVariableImpacts(string variableName, IEnumerable<DoubleMatrix> allVariableImpacts)
-        {
-            foreach (DoubleMatrix runVariableImpacts in allVariableImpacts)
-            {
-                int row = 0;
-                foreach (string rowName in runVariableImpacts.RowNames)
-                {
-                    if (rowName == variableName)
-                        yield return runVariableImpacts[row, 0];
-                    row++;
-                }
-            }
-        }
-
-        private void trackBar1_ValueChanged(object sender, EventArgs e)
-        {
-            genThreshold.Text = (0.001 * trackBar1.Value).ToString();
-            textBox1.Text = (0.001 * trackBar1.Minimum).ToString();
-            textBox2.Text = (0.001 * trackBar1.Maximum).ToString();
-            viewHost3.Content = UpdateAdjacencyMatrixByThreshold(0.001 * trackBar1.Value, (DoubleMatrix)viewHost3.Content);
-        }
-
-        private void mouseDownEvent(TrackBar tb, MouseEventArgs e)
-        {
-                double percentage = (double)e.X / (double)(tb.Width - 6);
-                double clickPos = percentage * (tb.Maximum - tb.Minimum);
-                try
-                {
-                    tb.Value = (int)clickPos + tb.Minimum;
-                }
-                catch
-                {
-                    MessageBox.Show("Value outside range!");
-                    return;
-                }
-        }
-
-        private void trackBar1_MouseDown(object sender, MouseEventArgs e)
-        {
-            mouseDownEvent(trackBar1, e);
-        }
-
-        private void trackBar2_MouseDown(object sender, MouseEventArgs e)
-        {
-            if (targetVariablesCombo.SelectedIndex < 0)
-            {
-                return;
-            }
-            else
-            {
-                mouseDownEvent(trackBar2, e);
-            }
-        }
-
-        private void trackBar2_ValueChanged(object sender, EventArgs e)
-        {
-            targetThreshold.Text = (0.001 * trackBar2.Value).ToString();
-
-            if (targetVariablesCombo.SelectedIndex < 0)
-            {
-                MessageBox.Show("Please select target variable!");
-                return;
-            }
-            else
-            {
-                string selectedItem = (string)targetVariablesCombo.Items[targetVariablesCombo.SelectedIndex];
-                viewHost3.Content = UpdateAdjacencyMatrixByThresholdAndTargetVariable(0.001 * trackBar2.Value, selectedItem, (DoubleMatrix)viewHost3.Content);
-            }
-        }
-
-        private void genThresholdEvent()
-        {
-            this.errorProvider.SetError(genThreshold, "");
-
-            if (genThreshold.Text != "")
-            {
-                if (Double.Parse(genThreshold.Text) >= GetMinNonNullElement((DoubleMatrix)viewHost1.Content) && Double.Parse(genThreshold.Text) <= ((DoubleMatrix)viewHost1.Content).Max())
-                {
-                    genThreshold.Select(genThreshold.Text.Length, 0);
-                    trackBar1.Value = (int)(1000 * Double.Parse(genThreshold.Text));
-                    viewHost3.Content = UpdateAdjacencyMatrixByThreshold(Double.Parse(genThreshold.Text), (DoubleMatrix)viewHost3.Content);
-                }
-                else
-                {
-                    this.errorProvider.SetError(genThreshold, "Value out of range!");
-                }
-            }
-            else
-            {
-                MessageBox.Show("Please select a threshold!");
-                this.errorProvider.SetError(genThreshold, "");
-                return;
-            }
-        }
-
-        private void genThreshold_TextChanged(object sender, EventArgs e)
-        {
-            genThresholdEvent();
-        }
-
-        private void genThreshold_KeyDown(object sender, KeyEventArgs e)
-        {
-            if (e.KeyCode == Keys.Enter)
-                genThresholdEvent();        
-        }
-
-        private void targetThresholdEvent()
-        {
-            this.errorProvider2.SetError(targetThreshold, "");
-
-            if (targetVariablesCombo.SelectedIndex < 0)
-            {
-                return;
-            }
-            else
-            {
-                string selectedItem = (string)targetVariablesCombo.Items[targetVariablesCombo.SelectedIndex];
-                if (Double.Parse(targetThreshold.Text) >= Double.Parse(textBox3.Text) && Double.Parse(targetThreshold.Text) <= Double.Parse(textBox4.Text))
-                {
-                    trackBar2.Value = (int)(1000 * Double.Parse(targetThreshold.Text));
-                }
-                else
-                {
-                    this.errorProvider2.SetError(targetThreshold, "Value out of range!");
-                    return;
-                }
-            }
-        }
-
-        private void targetThreshold_TextChanged(object sender, EventArgs e)
-        {
-            targetThresholdEvent();
-        }
-
-        private void targetThreshold_KeyDown(object sender, KeyEventArgs e)
-        {
-            if (e.KeyCode == Keys.Enter)
-            {
-                targetThresholdEvent();
-            }
-        }
-
-        private void targetVariablesCombo_Dropdown(object sender, System.EventArgs e)
-        {
-            targetVariablesCombo.Items.Clear();
-            string[] targetVariables = ((DoubleMatrix)viewHost3.Content).RowNames.ToArray();
-            targetVariablesCombo.Items.AddRange(targetVariables);
-        }
-
-        private void targetVariablesCombo_SelectedIndexChanged(object sender, System.EventArgs e)
-        {
-            var targetIndex = targetVariablesCombo.SelectedIndex;
-            string selectedItem = (string)targetVariablesCombo.Items[targetIndex];
-            trackBar2.Minimum = 0;
-            trackBar2.Maximum = (int)(1000 * GetMaxFromRow(targetIndex, (DoubleMatrix)viewHost1.Content));
-            textBox3.Text = trackBar2.Minimum.ToString();
-            textBox4.Text = (0.001 * trackBar2.Maximum).ToString();
-            UpdateAdjacencyMatrixByThresholdAndTargetVariable(0.001 * trackBar2.Value, selectedItem, (DoubleMatrix)viewHost3.Content);
-        }
-    }
-}
