Index: /branches/PerformanceComparison/Build.cmd
===================================================================
--- /branches/PerformanceComparison/Build.cmd	(revision 13667)
+++ /branches/PerformanceComparison/Build.cmd	(revision 13667)
@@ -0,0 +1,104 @@
+@ECHO OFF
+
+SET CLEANBEFOREBUILD=
+
+SET SELECTED=
+SET CONFIGURATION=
+SET PLATFORM=
+
+IF "%~1"=="" GOTO :prompt_solution
+
+SET SELECTED=%1
+IF NOT EXIST %SELECTED% (
+  ECHO Solution file %SELECTED% could not be found.
+  GOTO :end
+)
+ECHO Building solution %SELECTED% ...
+GOTO :config_selection
+
+:prompt_solution
+SET /A COUNT=0
+FOR /F "tokens=*" %%A IN ('dir /B *.sln') DO (
+  CALL :forloopbody "%%A"
+)
+
+IF "%COUNT%"=="1" (
+  SET SELECTED=%SOLUTIONS.1%
+  ECHO Building %SOLUTIONS.1% as it is the only solution that was found ...
+  GOTO :config_selection
+)
+
+ECHO Found the following solutions:
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO ECHO %%A = %%B
+ECHO.
+SET /P SOLUTIONINDEX=Which solution to build? Type the number: 
+
+SET SELECTED=""
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO (
+  IF "%%A"=="%SOLUTIONINDEX%" SET SELECTED=%%B
+)
+
+IF %SELECTED%=="" GOTO :eof
+
+:config_selection
+IF "%~2"==""  GOTO :prompt_config
+
+SET CONFIGURATION=%~2
+ECHO Building configuration %CONFIGURATION% ...
+GOTO :platform_selection
+
+:prompt_config
+SET /P CONFIGURATION=Which configuration to build [Release]: 
+IF "%CONFIGURATION%"=="" SET CONFIGURATION=Release
+
+:platform_selection
+IF "%~3"=="" GOTO :prompt_platform
+  
+SET PLATFORM=%~3
+ECHO Building platform %PLATFORM% ...
+GOTO :clean
+
+:prompt_platform
+SET /P PLATFORM=Which platform to build [Any CPU]: 
+IF "%PLATFORM%"=="" SET PLATFORM=Any CPU
+
+:clean
+IF "%~4"=="" GOTO :prompt_clean
+
+SET CLEANBEFOREBUILD=%~4
+GOTO :main
+
+:prompt_clean
+SET /P CLEANBEFOREBUILD=Would you like to clean before building [n]: 
+IF "%CLEANBEFOREBUILD%"=="" SET CLEANBEFOREBUILD=n
+
+:main
+REM First find the path to the msbuild.exe by performing a registry query
+FOR /F "tokens=1,3 delims=	 " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0"') DO (
+  IF "%%A"=="MSBuildToolsPath" SET MSBUILDPATH=%%B)
+
+REM Then execute msbuild to clean and build the solution
+REM Disable that msbuild creates a cache file of the solution
+SET MSBuildUseNoSolutionCache=1
+REM Run msbuild to clean and then build
+IF "%CLEANBEFOREBUILD%" NEQ "n" (
+  ECHO Cleaning ...
+  %MSBUILDPATH%msbuild.exe %SELECTED% /target:Clean /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+)
+ECHO Building ...
+%MSBUILDPATH%msbuild.exe %SELECTED% /target:Build /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+
+ECHO.
+ECHO DONE.
+
+:end
+
+PAUSE
+
+GOTO :eof
+
+REM This workaround is necessary so that COUNT gets reevaluated
+:forloopbody
+SET /A COUNT+=1
+SET SOLUTIONS.%COUNT%=%1
+GOTO :eof
Index: /branches/PerformanceComparison/Clean.cmd
===================================================================
--- /branches/PerformanceComparison/Clean.cmd	(revision 13667)
+++ /branches/PerformanceComparison/Clean.cmd	(revision 13667)
@@ -0,0 +1,30 @@
+@ECHO OFF
+
+ECHO Clean starting...
+
+FOR /F "tokens=*" %%G IN ('DIR /AD /B') DO (
+  FOR /F "tokens=*" %%T IN ('DIR /AD /B %%G') DO (
+    IF EXIST "%%G\%%T\bin" (
+      ECHO Cleaning "bin" in %%G in version %%T ...
+      RMDIR /S /Q "%%G\%%T\bin"
+    )
+    IF EXIST "%%G\%%T\obj" (
+      ECHO Cleaning "obj" in %%G in version %%T ...
+      RMDIR /S /Q "%%G\%%T\obj"
+    )
+  )
+)
+
+IF EXIST bin (
+  ECHO Cleaning "bin" in current directory ...
+  RMDIR /S /Q bin
+)
+
+IF EXIST TestResults (
+  ECHO Cleaning "TestResults" in current directory ...
+  RMDIR /S /Q TestResults
+)
+
+ECHO Clean finished.
+
+PAUSE
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/AdaptiveWalkCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/AdaptiveWalkCalculator.cs	(revision 13666)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/AdaptiveWalkCalculator.cs	(revision 13667)
@@ -67,4 +67,6 @@
         "Diversity", "Regularity", "TotalEntropy", "PeakInformationContent",
         "PeakDensityBasinInformation" }.Select(x => new StringValue(x)));
+      characteristics.SetItemCheckedState(1, false);
+      characteristics.SetItemCheckedState(5, false);
     }
 
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/RandomWalkCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/RandomWalkCalculator.cs	(revision 13666)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/RandomWalkCalculator.cs	(revision 13667)
@@ -67,4 +67,6 @@
         "Diversity", "Regularity", "TotalEntropy", "PeakInformationContent",
         "PeakDensityBasinInformation" }.Select(x => new StringValue(x)));
+      characteristics.SetItemCheckedState(1, false);
+      characteristics.SetItemCheckedState(5, false);
     }
 
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/UpDownWalkCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/UpDownWalkCalculator.cs	(revision 13666)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.FitnessLandscape/3.3/CharacteristicCalculator/UpDownWalkCalculator.cs	(revision 13667)
@@ -68,4 +68,8 @@
         "PeakDensityBasinInformation", "DownWalkLength", "UpWalkLength", "UpWalkLenVar",
         "DownWalkLenVar", "LowerVariance", "UpperVariance" }.Select(x => new StringValue(x)));
+      characteristics.SetItemCheckedState(1, false);
+      characteristics.SetItemCheckedState(5, false);
+      characteristics.SetItemCheckedState(15, false);
+      characteristics.SetItemCheckedState(16, false);
     }
 
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 13666)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 13667)
@@ -228,4 +228,10 @@
       <DependentUpon>CreateNewSingleEncodingDialog.cs</DependentUpon>
     </Compile>
+    <Compile Include="ICharacteristicCalculatorView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ICharacteristicCalculatorView.Designer.cs">
+      <DependentUpon>ICharacteristicCalculatorView.cs</DependentUpon>
+    </Compile>
     <Compile Include="IRRestarterView.cs">
       <SubType>UserControl</SubType>
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ICharacteristicCalculatorView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ICharacteristicCalculatorView.Designer.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ICharacteristicCalculatorView.Designer.cs	(revision 13667)
@@ -0,0 +1,120 @@
+﻿#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
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ICharacteristicCalculatorView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.parametersTabPage = new System.Windows.Forms.TabPage();
+      this.characteristicsTabPage = new System.Windows.Forms.TabPage();
+      this.parameterCollectionView = new HeuristicLab.Core.Views.ParameterCollectionView();
+      this.tabControl.SuspendLayout();
+      this.parametersTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // tabControl
+      // 
+      this.tabControl.Controls.Add(this.parametersTabPage);
+      this.tabControl.Controls.Add(this.characteristicsTabPage);
+      this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.tabControl.Location = new System.Drawing.Point(0, 0);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(764, 498);
+      this.tabControl.TabIndex = 0;
+      // 
+      // parametersTabPage
+      // 
+      this.parametersTabPage.Controls.Add(this.parameterCollectionView);
+      this.parametersTabPage.Location = new System.Drawing.Point(4, 22);
+      this.parametersTabPage.Name = "parametersTabPage";
+      this.parametersTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.parametersTabPage.Size = new System.Drawing.Size(756, 472);
+      this.parametersTabPage.TabIndex = 0;
+      this.parametersTabPage.Text = "Parameters";
+      this.parametersTabPage.UseVisualStyleBackColor = true;
+      // 
+      // characteristicsTabPage
+      // 
+      this.characteristicsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.characteristicsTabPage.Name = "characteristicsTabPage";
+      this.characteristicsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.characteristicsTabPage.Size = new System.Drawing.Size(756, 472);
+      this.characteristicsTabPage.TabIndex = 1;
+      this.characteristicsTabPage.Text = "Characteristics";
+      this.characteristicsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.AllowEditingOfHiddenParameters = true;
+      this.parameterCollectionView.Caption = "ParameterCollection View";
+      this.parameterCollectionView.Content = null;
+      this.parameterCollectionView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.parameterCollectionView.Location = new System.Drawing.Point(3, 3);
+      this.parameterCollectionView.Name = "parameterCollectionView";
+      this.parameterCollectionView.ReadOnly = false;
+      this.parameterCollectionView.ShowDetails = true;
+      this.parameterCollectionView.Size = new System.Drawing.Size(750, 466);
+      this.parameterCollectionView.TabIndex = 0;
+      // 
+      // ICharacteristicCalculatorView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl);
+      this.Name = "ICharacteristicCalculatorView";
+      this.Size = new System.Drawing.Size(764, 498);
+      this.tabControl.ResumeLayout(false);
+      this.parametersTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage parametersTabPage;
+    private Core.Views.ParameterCollectionView parameterCollectionView;
+    private System.Windows.Forms.TabPage characteristicsTabPage;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ICharacteristicCalculatorView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ICharacteristicCalculatorView.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ICharacteristicCalculatorView.cs	(revision 13667)
@@ -0,0 +1,55 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("ICharacteristicCalculatorView")]
+  [Content(typeof(ICharacteristicCalculator), IsDefaultView = true)]
+  public partial class ICharacteristicCalculatorView : ItemView {
+    private CheckedItemListView<StringValue> characteristicsView;
+
+    public new ICharacteristicCalculator Content {
+      get { return (ICharacteristicCalculator)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ICharacteristicCalculatorView() {
+      InitializeComponent();
+      characteristicsView = new CheckedItemListView<StringValue> { Dock = DockStyle.Fill };
+      characteristicsTabPage.Controls.Add(characteristicsView);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        parameterCollectionView.Content = null;
+        characteristicsView.Content = null;
+      } else {
+        parameterCollectionView.Content = Content.Parameters;
+        characteristicsView.Content = Content.Characteristics;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ExpertSystem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ExpertSystem.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ExpertSystem.cs	(revision 13667)
@@ -0,0 +1,632 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Analysis;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Persistence.Default.Xml;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using RunCreationClient = HeuristicLab.Clients.OKB.RunCreation.RunCreationClient;
+using SingleObjectiveOKBProblem = HeuristicLab.Clients.OKB.RunCreation.SingleObjectiveOKBProblem;
+
+namespace HeuristicLab.OptimizationExpertSystem.Common {
+  [Item("Expert-System", "Currently in experimental phase, an expert system that makes algorithm suggestions based on fitness landscape analysis features and an optimization knowledge base.")]
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 119)]
+  public sealed class ExpertSystem : NamedItem, IStorableContent, INotifyPropertyChanged {
+
+    public string Filename { get; set; }
+
+    public static new Image StaticItemImage {
+      get { return VSImageLibrary.Library; }
+    }
+
+    [Storable]
+    private int maximumEvaluations;
+    public int MaximumEvaluations {
+      get { return maximumEvaluations; }
+      set {
+        if (maximumEvaluations == value) return;
+        maximumEvaluations = value;
+        OnPropertyChanged("MaximumEvaluations");
+        UpdateSuggestions();
+      }
+    }
+
+    [Storable]
+    private RunCollection runs;
+    public RunCollection Runs {
+      get { return runs; }
+    }
+
+    [Storable]
+    private RunCollection knowledgeBase;
+    public RunCollection KnowledgeBase {
+      get { return knowledgeBase; }
+      set {
+        if (knowledgeBase == value) return;
+        knowledgeBase = value;
+        OnPropertyChanged("KnowledgeBase");
+      }
+    }
+
+    [Storable]
+    private SingleObjectiveOKBProblem problem;
+    public SingleObjectiveOKBProblem Problem {
+      get { return problem; }
+      set {
+        if (problem == value) return;
+        problem = value;
+        OnPropertyChanged("Problem");
+        UpdateSuggestions();
+      }
+    }
+
+    [Storable]
+    private ItemList<IAlgorithm> suggestedInstances;
+    private ReadOnlyItemList<IAlgorithm> readOnlySuggestedInstances;
+    public ReadOnlyItemList<IAlgorithm> SuggestedInstances {
+      get { return readOnlySuggestedInstances; }
+    }
+
+    [Storable]
+    private RunCollection problemInstances;
+    public RunCollection ProblemInstances {
+      get { return problemInstances; }
+      set {
+        if (problemInstances == value) return;
+        problemInstances = value;
+        OnPropertyChanged("ProblemInstances");
+      }
+    }
+
+    [Storable]
+    private ResultCollection currentResult;
+    public ResultCollection CurrentResult {
+      get { return currentResult; }
+      set {
+        if (currentResult == value) return;
+        currentResult = value;
+        OnPropertyChanged("CurrentResult");
+      }
+    }
+
+    [Storable(Name = "solutionPool")]
+    private ItemList<IScope> oldBackwardsCompatible;
+    [Storable(Name = "newSolutionPool")]
+    private CheckedItemList<IScope> solutionPool;
+    public CheckedItemList<IScope> SolutionPool {
+      get { return solutionPool; }
+      set {
+        if (solutionPool == value) return;
+        solutionPool = value;
+        OnPropertyChanged("SolutionPool");
+      }
+    }
+    
+    [Storable]
+    private BidirectionalLookup<long, IRun> algorithmId2RunMapping;
+    [Storable]
+    private BidirectionalDictionary<long, IAlgorithm> algorithmId2AlgorithmInstanceMapping;
+
+    [Storable]
+    private Run currentInstance;
+
+    private bool Maximization {
+      get {
+        return Problem != null && Problem.ProblemId >= 0 && ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value;
+      }
+    }
+
+    [StorableConstructor]
+    private ExpertSystem(bool deserializing) : base(deserializing) { }
+    private ExpertSystem(ExpertSystem original, Cloner cloner)
+      : base(original, cloner) {
+      runs = cloner.Clone(original.runs);
+      knowledgeBase = cloner.Clone(original.knowledgeBase);
+      suggestedInstances = cloner.Clone(original.suggestedInstances);
+      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
+      problemInstances = cloner.Clone(original.problemInstances);
+      problem = cloner.Clone(original.problem);
+      algorithmId2RunMapping = new BidirectionalLookup<long, IRun>();
+      foreach (var kvp in original.algorithmId2RunMapping.FirstEnumerable) {
+        algorithmId2RunMapping.AddRangeFirst(kvp.Key, kvp.Select(cloner.Clone));
+      }
+      algorithmId2AlgorithmInstanceMapping = new BidirectionalDictionary<long, IAlgorithm>();
+      foreach (var kvp in original.algorithmId2AlgorithmInstanceMapping) {
+        algorithmId2AlgorithmInstanceMapping.Add(kvp.Key, cloner.Clone(kvp.Value));
+      }
+      currentResult = cloner.Clone(original.currentResult);
+      solutionPool = cloner.Clone(original.solutionPool);
+      currentInstance = cloner.Clone(original.currentInstance);
+      RegisterEventHandlers();
+    }
+    public ExpertSystem() {
+      Name = ItemName;
+      Description = ItemDescription;
+      runs = new RunCollection();
+      knowledgeBase = new RunCollection();
+      suggestedInstances = new ItemList<IAlgorithm>();
+      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
+      problemInstances = new RunCollection();
+      problem = new SingleObjectiveOKBProblem();
+      solutionPool = new CheckedItemList<IScope>();
+      algorithmId2RunMapping = new BidirectionalLookup<long, IRun>();
+      algorithmId2AlgorithmInstanceMapping = new BidirectionalDictionary<long, IAlgorithm>();
+      RegisterEventHandlers();
+    }
+
+    private void ProblemOnProblemChanged(object sender, EventArgs eventArgs) {
+      if (Problem == null) return;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExpertSystem(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with trunk integration
+      if (oldBackwardsCompatible != null) solutionPool = new CheckedItemList<IScope>(solutionPool);
+      else if (solutionPool == null) solutionPool = new CheckedItemList<IScope>();
+      #endregion
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      problem.ProblemChanged += ProblemOnProblemChanged;
+      runs.CollectionReset += InformationChanged;
+      runs.ItemsAdded += InformationChanged;
+      runs.ItemsRemoved += InformationChanged;
+      runs.Reset += InformationChanged;
+      runs.UpdateOfRunsInProgressChanged += InformationChanged;
+      knowledgeBase.CollectionReset += InformationChanged;
+      knowledgeBase.ItemsAdded += InformationChanged;
+      knowledgeBase.ItemsRemoved += InformationChanged;
+    }
+
+    private void InformationChanged(object sender, EventArgs e) {
+      var runCollection = sender as RunCollection;
+      if (runCollection != null && runCollection.UpdateOfRunsInProgress) return;
+      UpdateSuggestions();
+    }
+
+    public void UpdateInstanceProjection() {
+      currentInstance = null;
+      var filter = new HashSet<string>();
+
+      if (Problem.ProblemId != -1) {
+        currentInstance = new Run { Name = Problem.Name };
+        Problem.Problem.CollectParameterValues(currentInstance.Parameters);
+        foreach (var c in RunCreationClient.GetCharacteristicValues(Problem.ProblemId)) {
+          var key = "Characteristic." + c.Name;
+          currentInstance.Results.Add(key, RunCreationClient.Instance.ConvertToItem(c));
+          filter.Add(key);
+        }
+      }
+      // TODO: There is a problem with missing values that has to be solved
+      // The common set of characteristics among all problems may be too small to be useful
+      // It has to be decided somehow which problem instances to include in order to obtain the set of features that is expressive and available
+      var allCharacteristics = ProblemInstances.Select(x => new HashSet<string>(x.Results.Where(y => y.Key.StartsWith("Characteristic.", StringComparison.Ordinal)).Select(y => y.Key))).ToList();
+      var commonCharacteristics = filter.Count > 0 ? filter : allCharacteristics[0];
+      for (var i = 0; i < allCharacteristics.Count; i++)
+        commonCharacteristics.IntersectWith(allCharacteristics[i]);
+
+      if (commonCharacteristics.Count == 0) return;
+
+      var instances = new Dictionary<string, double[]>();
+      foreach (var i in ProblemInstances)
+        instances[i.Name] = i.Results.Where(x => commonCharacteristics.Contains(x.Key)).OrderBy(x => x.Key).Select(x => (double)((dynamic)x.Value).Value).ToArray();
+      if (currentInstance != null)
+        instances[currentInstance.Name] = currentInstance.Results.Where(x => commonCharacteristics.Contains(x.Key)).OrderBy(x => x.Key).Select(x => (double)((dynamic)x.Value).Value).ToArray();
+
+      var allValues = instances.SelectMany(x => x.Value).ToList();
+      var avg = allValues.Average();
+      var stdev = allValues.StandardDeviation();
+
+      // normalize characteristic values by transforming them to their z-score
+      foreach (var key in instances.Keys.ToList()) {
+        var arr = instances[key];
+        for (var i = 0; i < arr.Length; i++) {
+          arr[i] = (arr[i] - avg) / stdev;
+        }
+      }
+
+      var key2Idx = new BidirectionalDictionary<string, int>();
+      foreach (var kvp in instances.Select((k, i) => new { Index = i, Key = k.Key }))
+        key2Idx.Add(kvp.Key, kvp.Index);
+
+      #region MDS
+      Func<double[], double[], double> euclid = (a, b) => Math.Sqrt(a.Zip(b, (x, y) => (x - y)).Sum(x => x * x));
+      var num = instances.Count;
+      var matrix = new DoubleMatrix(num, num);
+      for (var i = 0; i < num - 1; i++) {
+        for (var j = i + 1; j < num; j++) {
+          matrix[i, j] = matrix[j, i] = euclid(instances[key2Idx.GetBySecond(i)], instances[key2Idx.GetBySecond(j)]);
+        }
+      }
+
+      var coords = MultidimensionalScaling.KruskalShepard(matrix);
+      #endregion
+      #region PCA
+      var ds = new double[instances.Count, commonCharacteristics.Count];
+      foreach (var instance in instances) {
+        var arr = instance.Value;
+        for (var feature = 0; feature < arr.Length; feature++)
+          ds[key2Idx.GetByFirst(instance.Key), feature] = arr[feature];
+      }
+
+      int info;
+      double[] s2;
+      double[,] v;
+      alglib.pcabuildbasis(ds, ds.GetLength(0), ds.GetLength(1), out info, out s2, out v);
+      #endregion
+
+      ProblemInstances.UpdateOfRunsInProgress = true;
+      try {
+        foreach (var instance in ProblemInstances) {
+          double x = 0, y = 0;
+          for (var feature = 0; feature < ds.GetLength(1); feature++) {
+            x += ds[key2Idx.GetByFirst(instance.Name), feature] * v[feature, 0];
+            y += ds[key2Idx.GetByFirst(instance.Name), feature] * v[feature, 1];
+          }
+
+          IItem item;
+          if (instance.Results.TryGetValue("Projection.PCA.X", out item)) {
+            ((DoubleValue)item).Value = x;
+          } else instance.Results.Add("Projection.PCA.X", new DoubleValue(x));
+          if (instance.Results.TryGetValue("Projection.PCA.Y", out item)) {
+            ((DoubleValue)item).Value = y;
+          } else instance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
+
+          if (instance.Results.TryGetValue("Projection.MDS.X", out item)) {
+            ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(instance.Name), 0];
+          } else instance.Results.Add("Projection.MDS.X", new DoubleValue(coords[key2Idx.GetByFirst(instance.Name), 0]));
+          if (instance.Results.TryGetValue("Projection.MDS.Y", out item)) {
+            ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(instance.Name), 1];
+          } else instance.Results.Add("Projection.MDS.Y", new DoubleValue(coords[key2Idx.GetByFirst(instance.Name), 1]));
+        }
+      } finally { ProblemInstances.UpdateOfRunsInProgress = false; }
+
+      if (currentInstance != null) {
+        double x = 0, y = 0;
+        for (var feature = 0; feature < ds.GetLength(1); feature++) {
+          x += ds[key2Idx.GetByFirst(currentInstance.Name), feature] * v[feature, 0];
+          y += ds[key2Idx.GetByFirst(currentInstance.Name), feature] * v[feature, 1];
+        }
+
+        IItem item;
+        if (currentInstance.Results.TryGetValue("Projection.PCA.X", out item)) {
+          ((DoubleValue)item).Value = x;
+        } else currentInstance.Results.Add("Projection.PCA.X", new DoubleValue(x));
+        if (currentInstance.Results.TryGetValue("Projection.PCA.Y", out item)) {
+          ((DoubleValue)item).Value = y;
+        } else currentInstance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
+
+        if (currentInstance.Results.TryGetValue("Projection.MDS.X", out item)) {
+          ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(currentInstance.Name), 0];
+        } else currentInstance.Results.Add("Projection.MDS.X", new DoubleValue(coords[key2Idx.GetByFirst(currentInstance.Name), 0]));
+        if (currentInstance.Results.TryGetValue("Projection.MDS.Y", out item)) {
+          ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(currentInstance.Name), 1];
+        } else currentInstance.Results.Add("Projection.MDS.Y", new DoubleValue(coords[key2Idx.GetByFirst(currentInstance.Name), 1]));
+      }
+    }
+
+    public Tuple<double, double> ProjectCurrentInstance(string projection) {
+      if (currentInstance == null) return null;
+      var xKey = "Projection." + projection + ".X";
+      var yKey = "Projection." + projection + ".Y";
+      if (!currentInstance.Results.ContainsKey(xKey) || !currentInstance.Results.ContainsKey(yKey))
+        return null;
+      var x = ((DoubleValue)currentInstance.Results[xKey]).Value;
+      var y = ((DoubleValue)currentInstance.Results[yKey]).Value;
+      return Tuple.Create(x, y);
+    }
+
+    private static readonly HashSet<string> InterestingValueNames = new HashSet<string>() {
+      "QualityPerEvaluations", "Problem Name", "Problem Type", "Algorithm Name", "Algorithm Type", "Maximization", "BestKnownQuality"
+    };
+
+    public void StartAlgorithmAsync(int index) {
+      var selectedInstance = suggestedInstances[index];
+      var algorithm = (IAlgorithm)selectedInstance.Clone();
+      algorithm.Prepare(true);
+      IParameter stopParam;
+      var monitorStop = true;
+      if (algorithm.Parameters.TryGetValue("MaximumEvaluations", out stopParam)) {
+        var maxEvalParam = stopParam as IValueParameter<Data.IntValue>;
+        if (maxEvalParam != null) {
+          maxEvalParam.Value.Value = MaximumEvaluations;
+          monitorStop = false;
+        }
+      }
+      algorithm.ExecutionStateChanged += AlgorithmOnExecutionStateChanged;
+      algorithm.ExceptionOccurred += AlgorithmOnExceptionOccurred;
+      if (monitorStop) algorithm.ExecutionTimeChanged += AlgorithmOnExecutionTimeChanged;
+
+      algorithm.Start();
+    }
+
+    public void StartAlgorithm(int index) {
+      var selectedInstance = suggestedInstances[index];
+      var algorithm = (IAlgorithm)selectedInstance.Clone();
+      algorithm.Prepare(true);
+      IParameter stopParam;
+      var monitorStop = true;
+      if (algorithm.Parameters.TryGetValue("MaximumEvaluations", out stopParam)) {
+        var maxEvalParam = stopParam as IValueParameter<Data.IntValue>;
+        if (maxEvalParam != null) {
+          maxEvalParam.Value.Value = MaximumEvaluations;
+          monitorStop = false;
+        }
+      }
+      algorithm.ExecutionStateChanged += AlgorithmOnExecutionStateChanged;
+      algorithm.ExceptionOccurred += AlgorithmOnExceptionOccurred;
+      if (monitorStop) algorithm.ExecutionTimeChanged += AlgorithmOnExecutionTimeChanged;
+
+      using (algWh = new AutoResetEvent(false)) {
+        algorithm.Start();
+        algWh.WaitOne();
+      }
+      algWh = null;
+    }
+
+    private AutoResetEvent algWh;
+
+    private void AlgorithmOnExecutionStateChanged(object sender, EventArgs eventArgs) {
+      var alg = sender as IAlgorithm;
+      if (alg == null) return;
+      if (alg.ExecutionState == ExecutionState.Started) {
+        CurrentResult = alg.Results;
+      } else if (alg.ExecutionState == ExecutionState.Stopped) {
+        alg.ExecutionStateChanged -= AlgorithmOnExecutionStateChanged;
+        alg.ExceptionOccurred -= AlgorithmOnExceptionOccurred;
+        alg.ExecutionTimeChanged -= AlgorithmOnExecutionTimeChanged;
+        foreach (var solution in alg.Results.Where(x => x.Name.ToLower().Contains("solution")).Select(x => x.Value).OfType<IScope>()) {
+          solutionPool.Add(solution);
+        }
+        Runs.Add(alg.Runs.Last());
+        if (algWh != null) algWh.Set();
+      }
+    }
+
+    private void AlgorithmOnExceptionOccurred(object sender, EventArgs<Exception> eventArgs) {
+      var alg = sender as IAlgorithm;
+      if (alg == null) return;
+      alg.ExecutionStateChanged -= AlgorithmOnExecutionStateChanged;
+      alg.ExceptionOccurred -= AlgorithmOnExceptionOccurred;
+      alg.ExecutionTimeChanged -= AlgorithmOnExecutionTimeChanged;
+      if (algWh != null) algWh.Set();
+    }
+
+    private void AlgorithmOnExecutionTimeChanged(object sender, EventArgs eventArgs) {
+      var alg = sender as IAlgorithm;
+      if (alg == null) return;
+      IResult evalSolResult;
+      if (!alg.Results.TryGetValue("EvaluatedSolutions", out evalSolResult) || !(evalSolResult.Value is Data.IntValue)) return;
+      var evalSols = ((Data.IntValue)evalSolResult.Value).Value;
+      if (evalSols >= MaximumEvaluations) alg.Stop();
+    }
+
+    public async void UpdateKnowledgeBaseAsync(IProgress progress) {
+      progress.Start("Updating Knowledge Base from OKB");
+      await Task.Factory.StartNew(() => { DoUpdateKnowledgeBase(progress); }, TaskCreationOptions.LongRunning);
+    }
+
+    public void UpdateKnowledgeBase() {
+      DoUpdateKnowledgeBase(new Progress(string.Empty, ProgressState.Started));
+    }
+
+    private void DoUpdateKnowledgeBase(IProgress progress) {
+      var queryClient = Clients.OKB.Query.QueryClient.Instance;
+      var adminClient = Clients.OKB.Administration.AdministrationClient.Instance;
+      try {
+        progress.Status = "Downloading run information...";
+        progress.ProgressValue = 0;
+        // FIXME: How to tell if refresh is necessary?
+        queryClient.Refresh();
+        progress.ProgressValue = 0.5;
+        progress.Status = "Downloading algorithm and problem instance information...";
+        // FIXME: How to tell if refresh is necessary?
+        adminClient.Refresh();
+
+        var probInstance = adminClient.Problems.SingleOrDefault(x => x.Id == Problem.ProblemId);
+        if (probInstance == null) throw new InvalidOperationException("The chosen problem instance cannot be found in the OKB.");
+        var probClassId = probInstance.ProblemClassId;
+
+        var problemClassFilter = (Clients.OKB.Query.StringComparisonAvailableValuesFilter)queryClient.Filters.Single(x => x.Label == "Problem Class Name");
+        problemClassFilter.Value = adminClient.ProblemClasses.Single(x => x.Id == probClassId).Name;
+
+        progress.Status = "Downloading problem instances...";
+        progress.ProgressValue = 0;
+        var p = 0;
+        ProblemInstances.UpdateOfRunsInProgress = true;
+        ProblemInstances.Clear();
+        var totalProblems = adminClient.Problems.Count(x => x.ProblemClassId == probClassId);
+        foreach (var problInst in adminClient.Problems.Where(x => x.ProblemClassId == probClassId)) {
+          progress.Status = string.Format("Downloading problem {0} (okb-id: {1})....", problInst.Name, problInst.Id);
+          var data = Clients.OKB.Administration.AdministrationClient.GetProblemData(problInst.Id);
+          if (data != null) {
+            using (var stream = new MemoryStream(data)) {
+              try {
+                var prob = (IProblem)XmlParser.Deserialize<IContent>(stream);
+                var probRun = new Run() { Name = prob.Name };
+                prob.CollectParameterValues(probRun.Parameters);
+                probRun.Parameters["Problem Name"] = new StringValue(prob.Name);
+                probRun.Parameters["Problem Type"] = new StringValue(prob.GetType().Name);
+                progress.Status += Environment.NewLine + "Downloading characteristics...";
+                foreach (var v in RunCreationClient.GetCharacteristicValues(problInst.Id)) {
+                  probRun.Results.Add("Characteristic." + v.Name, RunCreationClient.Instance.ConvertToItem(v));
+                }
+                ProblemInstances.Add(probRun);
+              } catch { }
+              stream.Close();
+            }
+          }
+          p++;
+          progress.ProgressValue = p / (double)totalProblems;
+        }
+
+        algorithmId2AlgorithmInstanceMapping.Clear();
+        progress.Status = "Downloading algorithm instances...";
+        progress.ProgressValue = 0;
+        p = 0;
+        foreach (var algInst in adminClient.Algorithms) {
+          progress.Status = string.Format("Downloading algorithm {0} (okb-id: {1})...", algInst.Name, algInst.Id);
+          var data = Clients.OKB.Administration.AdministrationClient.GetAlgorithmData(algInst.Id);
+          if (data != null) {
+            using (var stream = new MemoryStream(data)) {
+              try {
+                var alg = (IAlgorithm)XmlParser.Deserialize<IContent>(stream);
+                algorithmId2AlgorithmInstanceMapping.Add(algInst.Id, alg);
+              } catch { }
+              stream.Close();
+            }
+          }
+          p++;
+          progress.ProgressValue = p / (double)adminClient.Algorithms.Count;
+        }
+
+        var interestingValues = queryClient.ValueNames.Where(x => InterestingValueNames.Contains(x.Name)).ToList();
+
+        progress.Status = "Obtaining number of runs...";
+        progress.ProgressValue = 0;
+        p = 0;
+        var count = queryClient.GetNumberOfRuns(problemClassFilter);
+        if (count == 0) return;
+        
+        var runIds = queryClient.GetRunIds(problemClassFilter).ToList();
+        var conversions = new List<Task>();
+        var runList = new List<IRun>();
+        while (p < count) {
+          var nextIds = runIds.Skip(p).Take(500).ToList();
+          progress.Status = string.Format("Downloading runs {0} to {1} of {2}...", p, p + nextIds.Count, count);
+          var okbRuns = queryClient.GetRunsWithValues(nextIds, true, interestingValues);
+          conversions.Add(Task.Factory.StartNew(() => {
+            var hlRuns = okbRuns.AsParallel().Select(x => new { AlgorithmId = x.Algorithm.Id, Run = queryClient.ConvertToOptimizationRun(x) }).ToList();
+            lock (runList) {
+              foreach (var r in hlRuns) {
+                algorithmId2RunMapping.Add(r.AlgorithmId, r.Run);
+                runList.Add(r.Run);
+              }
+            }
+          }));
+          p += nextIds.Count;
+          progress.ProgressValue = p / (double)count;
+        }
+        Task.WaitAll(conversions.ToArray());
+
+        progress.Status = "Finishing...";
+        var algInstRunDict = runList.Where(x => x.Parameters.ContainsKey("Problem Name") && x.Parameters["Problem Name"] is StringValue)
+                                          .GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value)
+                                          .ToDictionary(x => x.Key, x => x.GroupBy(y => ((StringValue)y.Parameters["Algorithm Name"]).Value)
+                                                                                  .ToDictionary(y => y.Key, y => y.ToList()));
+
+        foreach (var instance in ProblemInstances) {
+          IItem probNameParam;
+          if (!instance.Parameters.TryGetValue("Problem Name", out probNameParam)) continue;
+
+          var probInstanceName = ((StringValue)probNameParam).Value;
+          var maximization = ((BoolValue)instance.Parameters["Maximization"]).Value;
+          
+          IItem bkParam;
+          if (!instance.Parameters.TryGetValue("BestKnownQuality", out bkParam) || !(bkParam is DoubleValue)) {
+            Dictionary<string, List<IRun>> algRuns;
+            if (!algInstRunDict.TryGetValue(probInstanceName, out algRuns)) continue;
+            var list = algRuns.SelectMany(x => x.Value)
+                              .Where(x => x.Results.ContainsKey("QualityPerEvaluations"))
+                              .Select(x => ((IndexedDataTable<double>)x.Results["QualityPerEvaluations"]).Rows.First().Values.Last().Item2);
+            bkParam = new DoubleValue(maximization ? list.Max() : list.Min());
+            instance.Parameters["BestKnownQuality"] = bkParam;
+          } else bkParam = instance.Parameters["BestKnownQuality"];
+
+          var bkQuality = ((DoubleValue)bkParam).Value;
+
+          if (!algInstRunDict.ContainsKey(probInstanceName)) continue;
+          foreach (var kvp in algInstRunDict[probInstanceName]) {
+            // TODO: Things needs to be configurable here (table name, targets)
+            foreach (var target in new[] { 1, 1.01, 1.05, 1.1, 1.2, 1.5 }) {
+              var result = ExpectedRuntimeHelper.CalculateErt(kvp.Value, "QualityPerEvaluations", bkQuality * target, maximization);
+              var resultName = kvp.Key + "@" + ((target - 1) * 100) + "%";
+              IItem item;
+              if (instance.Results.TryGetValue(resultName, out item)) {
+                ((DoubleValue)item).Value = Math.Log10(result.ExpectedRuntime);
+              } else instance.Results.Add(resultName, new DoubleValue(Math.Log10(result.ExpectedRuntime)));
+            }
+          }
+        }
+        KnowledgeBase = new RunCollection(runList);
+      } finally { progress.Finish(); ProblemInstances.UpdateOfRunsInProgress = false; }
+    }
+
+    private void UpdateSuggestions() {
+      if (Problem == null) return;
+      var instances = new SortedList<double, IAlgorithm>();
+      foreach (var relevantRuns in knowledgeBase.GroupBy(x => algorithmId2RunMapping.GetBySecond(x).Single())) {
+        var algorithm = algorithmId2AlgorithmInstanceMapping.GetByFirst(relevantRuns.Key);
+        var avgQuality = 0.0;
+        var counter = 0;
+        foreach (var problemRuns in relevantRuns.GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value)) {
+          var probInstance = ProblemInstances.SingleOrDefault(x => x.Name == problemRuns.Key);
+          if (probInstance == null) continue;
+          var bkQuality = ((DoubleValue)probInstance.Parameters["BestKnownQuality"]).Value;
+          foreach (var run in problemRuns) {
+            var performanceGraph = ((IndexedDataTable<double>)run.Results["QualityPerEvaluations"]);
+            try {
+              avgQuality += performanceGraph.Rows.First().Values.TakeWhile(x => x.Item1 < MaximumEvaluations).Last().Item2 / bkQuality;
+              counter++;
+            } catch {
+              continue;
+            }
+          }
+        }
+        avgQuality /= counter;
+        instances.Add(avgQuality, algorithm);
+      }
+
+      suggestedInstances.Clear();
+      var instanceLadder = instances.Select(x => (IAlgorithm)x.Value.Clone()).ToList();
+      if (Maximization) instanceLadder.Reverse();
+      suggestedInstances.AddRange(instanceLadder);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    private void OnPropertyChanged(string propertyName) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj	(revision 13667)
@@ -0,0 +1,180 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{492CC257-E27C-4497-B2C1-09C45310C91C}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.OptimizationExpertSystem.Common</RootNamespace>
+    <AssemblyName>HeuristicLab.OptimizationExpertSystem.Common-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.7.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Clients.OKB-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Clients.OKB-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.QuadraticAssignment-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.QuadraticAssignment-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ExpertSystem.cs" />
+    <Compile Include="Plugin.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <Compile Include="ProblemCharacteristicAnalysis\CharacteristicCalculator.cs" />
+    <Compile Include="ProblemCharacteristicAnalysis\DoubleMatrixCharacteristicCalculator.cs" />
+    <Compile Include="ProblemCharacteristicAnalysis\QAP\QAPCharacteristicCalculator.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Plugin.cs.frame	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Plugin.cs.frame	(revision 13667)
@@ -0,0 +1,41 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.OptimizationExpertSystem.Common {
+  /// <summary>
+  /// Plugin class for HeuristicLab.OptimizationExpertSystem plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.OptimizationExpertSystem.Common", "3.3.12.$WCREV$")]
+  [PluginFile("HeuristicLab.OptimizationExpertSystem.Common-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabOptimizationExpertSystemCommonPlugin : PluginBase {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/CharacteristicCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/CharacteristicCalculator.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/CharacteristicCalculator.cs	(revision 13667)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.CharacteristicAnalysis {
+  [Item("Characteristic Calculator", "")]
+  [StorableClass]
+  public abstract class CharacteristicCalculator : ParameterizedNamedItem, ICharacteristicCalculator {
+
+    [Storable]
+    public IProblem Problem { get; set; }
+
+    [Storable]
+    protected CheckedItemList<StringValue> characteristics;
+    public ReadOnlyCheckedItemList<StringValue> Characteristics { get { return characteristics.AsReadOnly(); } }
+
+    [StorableConstructor]
+    protected CharacteristicCalculator(bool deserializing) : base(deserializing) { }
+    protected CharacteristicCalculator(CharacteristicCalculator original, Cloner cloner)
+      : base(original, cloner) {
+      characteristics = cloner.Clone(original.characteristics);
+      Problem = cloner.Clone(original.Problem);
+    }
+    protected CharacteristicCalculator()
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      characteristics = new CheckedItemList<StringValue>();
+    }
+
+    public abstract bool CanCalculate();
+
+    public abstract IEnumerable<IResult> Calculate();
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/DoubleMatrixCharacteristicCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/DoubleMatrixCharacteristicCalculator.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/DoubleMatrixCharacteristicCalculator.cs	(revision 13667)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using System;
+using System.Linq;
+
+namespace HeuristicLab.Problems.CharacteristicAnalysis {
+  public static class DoubleMatrixCharacteristicCalculator {
+    public static double CoeffVariation(DoubleMatrix m) {
+      var avg = m.Average();
+      var stdDev = m.StandardDeviation();
+      return stdDev / avg;
+    }
+
+    public static double Sparsity(DoubleMatrix m) {
+      return m.Count(x => x == 0) / (double)(m.Rows * m.Columns);
+    }
+
+    public static double Disparity(DoubleMatrix m) {
+      if (m.Rows != m.Columns) throw new ArgumentException("not a quadratic matrix", "m");
+      var n = m.Rows;
+      var avg = m.Sum() / n;
+      var disparity = 0.0;
+      for (var i = 0; i < n; i++) {
+        var tmp = 0.0;
+        for (var j = 0; j < n; j++) {
+          tmp += m[i, j];
+        }
+        disparity += (tmp - avg) * (tmp - avg);
+      }
+      return Math.Sqrt(disparity / n) / avg;
+    }
+
+    public static double Skewness(DoubleMatrix m) {
+      double mean = 0, variance = 0, skewness = 0, kurtosis = 0;
+      alglib.basestat.samplemoments(m.ToArray(), m.Rows * m.Columns, ref mean, ref variance, ref skewness, ref kurtosis);
+      return skewness;
+    }
+
+    public static double Asymmetry(DoubleMatrix m) {
+      if (m.Rows != m.Columns) throw new ArgumentException("not a quadratic matrix", "m");
+      var n = m.Rows;
+      var count = 0;
+      for (var i = 0; i < n; i++) {
+        for (var j = 0; j < i; j++) {
+          var v = Math.Abs(m[i, j] - m[j, i]);
+          if (v > 0) {
+            count++;
+          }
+        }
+      }
+      return count / (n * (n - 1) / 2.0);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/QAP/QAPCharacteristicCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/QAP/QAPCharacteristicCalculator.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/ProblemCharacteristicAnalysis/QAP/QAPCharacteristicCalculator.cs	(revision 13667)
@@ -0,0 +1,86 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.QuadraticAssignment;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Problems.CharacteristicAnalysis.QAP {
+  [Item("QAP Characteristic Calculator", "")]
+  [StorableClass]
+  public sealed class QAPCharacteristicCalculator : CharacteristicCalculator {
+
+    [StorableConstructor]
+    private QAPCharacteristicCalculator(bool deserializing) : base(deserializing) { }
+    private QAPCharacteristicCalculator(QAPCharacteristicCalculator original, Cloner cloner) : base(original, cloner) { }
+    public QAPCharacteristicCalculator() {
+      characteristics.AddRange(new[] { "Dimension",
+        "FlowDominance", "DistanceDominance",
+        "FlowAsymmetry", "DistanceAsymmetry",
+        "FlowSparsity", "DistanceSparsity",
+        "FlowSkewness", "DistanceSkewness",
+        "FlowDisparity", "DistanceDisparity" }.Select(x => new StringValue(x)).ToList());
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QAPCharacteristicCalculator(this, cloner);
+    }
+
+    public override bool CanCalculate() {
+      return Problem is QuadraticAssignmentProblem;
+    }
+
+    public override IEnumerable<IResult> Calculate() {
+      var qap = Problem as QuadraticAssignmentProblem;
+      if (qap == null) throw new ArgumentException("Instance is not of type QuadraticAssignmentProblem");
+      foreach (var chara in characteristics.CheckedItems.Select(x => x.Value.Value)) {
+        if (chara == "Dimension")
+          yield return new Result(chara, new IntValue(qap.Weights.Rows));
+        if (chara == "FlowDominance")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariation(qap.Weights)));
+        if (chara == "DistanceDominance")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariation(qap.Distances)));
+        if (chara == "FlowAsymmetry")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Asymmetry(qap.Weights)));
+        if (chara == "DistanceAsymmetry")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Asymmetry(qap.Distances)));
+        if (chara == "FlowSparsity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(qap.Weights)));
+        if (chara == "DistanceSparsity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(qap.Distances)));
+        if (chara == "FlowSkewness")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Skewness(qap.Weights)));
+        if (chara == "DistanceSkewness")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Skewness(qap.Distances)));
+        if (chara == "FlowDisparity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Disparity(qap.Weights)));
+        if (chara == "DistanceDisparity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Disparity(qap.Distances)));
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Properties/AssemblyInfo.cs.frame	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/Properties/AssemblyInfo.cs.frame	(revision 13667)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.OptimizationExpertSystem.Common")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2016 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9b7ac6bf-de48-4049-a031-26c97e91dc3e")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.12.$WCREV$")]
Index: anches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystem.cs	(revision 13666)
+++ 	(revision )
@@ -1,632 +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 HeuristicLab.Analysis;
-using HeuristicLab.Collections;
-using HeuristicLab.Common;
-using HeuristicLab.Common.Resources;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.MainForm;
-using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Persistence.Default.Xml;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using RunCreationClient = HeuristicLab.Clients.OKB.RunCreation.RunCreationClient;
-using SingleObjectiveOKBProblem = HeuristicLab.Clients.OKB.RunCreation.SingleObjectiveOKBProblem;
-
-namespace HeuristicLab.OptimizationExpertSystem.Common {
-  [Item("Expert-System", "Currently in experimental phase, an expert system that makes algorithm suggestions based on fitness landscape analysis features and an optimization knowledge base.")]
-  [StorableClass]
-  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 119)]
-  public sealed class ExpertSystem : NamedItem, IStorableContent, INotifyPropertyChanged {
-
-    public string Filename { get; set; }
-
-    public static new Image StaticItemImage {
-      get { return VSImageLibrary.Library; }
-    }
-
-    [Storable]
-    private int maximumEvaluations;
-    public int MaximumEvaluations {
-      get { return maximumEvaluations; }
-      set {
-        if (maximumEvaluations == value) return;
-        maximumEvaluations = value;
-        OnPropertyChanged("MaximumEvaluations");
-        UpdateSuggestions();
-      }
-    }
-
-    [Storable]
-    private RunCollection runs;
-    public RunCollection Runs {
-      get { return runs; }
-    }
-
-    [Storable]
-    private RunCollection knowledgeBase;
-    public RunCollection KnowledgeBase {
-      get { return knowledgeBase; }
-      set {
-        if (knowledgeBase == value) return;
-        knowledgeBase = value;
-        OnPropertyChanged("KnowledgeBase");
-      }
-    }
-
-    [Storable]
-    private SingleObjectiveOKBProblem problem;
-    public SingleObjectiveOKBProblem Problem {
-      get { return problem; }
-      set {
-        if (problem == value) return;
-        problem = value;
-        OnPropertyChanged("Problem");
-        UpdateSuggestions();
-      }
-    }
-
-    [Storable]
-    private ItemList<IAlgorithm> suggestedInstances;
-    private ReadOnlyItemList<IAlgorithm> readOnlySuggestedInstances;
-    public ReadOnlyItemList<IAlgorithm> SuggestedInstances {
-      get { return readOnlySuggestedInstances; }
-    }
-
-    [Storable]
-    private RunCollection problemInstances;
-    public RunCollection ProblemInstances {
-      get { return problemInstances; }
-      set {
-        if (problemInstances == value) return;
-        problemInstances = value;
-        OnPropertyChanged("ProblemInstances");
-      }
-    }
-
-    [Storable]
-    private ResultCollection currentResult;
-    public ResultCollection CurrentResult {
-      get { return currentResult; }
-      set {
-        if (currentResult == value) return;
-        currentResult = value;
-        OnPropertyChanged("CurrentResult");
-      }
-    }
-
-    [Storable(Name = "solutionPool")]
-    private ItemList<IScope> oldBackwardsCompatible;
-    [Storable(Name = "newSolutionPool")]
-    private CheckedItemList<IScope> solutionPool;
-    public CheckedItemList<IScope> SolutionPool {
-      get { return solutionPool; }
-      set {
-        if (solutionPool == value) return;
-        solutionPool = value;
-        OnPropertyChanged("SolutionPool");
-      }
-    }
-    
-    [Storable]
-    private BidirectionalLookup<long, IRun> algorithmId2RunMapping;
-    [Storable]
-    private BidirectionalDictionary<long, IAlgorithm> algorithmId2AlgorithmInstanceMapping;
-
-    [Storable]
-    private Run currentInstance;
-
-    private bool Maximization {
-      get {
-        return Problem != null && Problem.ProblemId >= 0 && ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value;
-      }
-    }
-
-    [StorableConstructor]
-    private ExpertSystem(bool deserializing) : base(deserializing) { }
-    private ExpertSystem(ExpertSystem original, Cloner cloner)
-      : base(original, cloner) {
-      runs = cloner.Clone(original.runs);
-      knowledgeBase = cloner.Clone(original.knowledgeBase);
-      suggestedInstances = cloner.Clone(original.suggestedInstances);
-      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
-      problemInstances = cloner.Clone(original.problemInstances);
-      problem = cloner.Clone(original.problem);
-      algorithmId2RunMapping = new BidirectionalLookup<long, IRun>();
-      foreach (var kvp in original.algorithmId2RunMapping.FirstEnumerable) {
-        algorithmId2RunMapping.AddRangeFirst(kvp.Key, kvp.Select(cloner.Clone));
-      }
-      algorithmId2AlgorithmInstanceMapping = new BidirectionalDictionary<long, IAlgorithm>();
-      foreach (var kvp in original.algorithmId2AlgorithmInstanceMapping) {
-        algorithmId2AlgorithmInstanceMapping.Add(kvp.Key, cloner.Clone(kvp.Value));
-      }
-      currentResult = cloner.Clone(original.currentResult);
-      solutionPool = cloner.Clone(original.solutionPool);
-      currentInstance = cloner.Clone(original.currentInstance);
-      RegisterEventHandlers();
-    }
-    public ExpertSystem() {
-      Name = ItemName;
-      Description = ItemDescription;
-      runs = new RunCollection();
-      knowledgeBase = new RunCollection();
-      suggestedInstances = new ItemList<IAlgorithm>();
-      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
-      problemInstances = new RunCollection();
-      problem = new SingleObjectiveOKBProblem();
-      solutionPool = new CheckedItemList<IScope>();
-      algorithmId2RunMapping = new BidirectionalLookup<long, IRun>();
-      algorithmId2AlgorithmInstanceMapping = new BidirectionalDictionary<long, IAlgorithm>();
-      RegisterEventHandlers();
-    }
-
-    private void ProblemOnProblemChanged(object sender, EventArgs eventArgs) {
-      if (Problem == null) return;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ExpertSystem(this, cloner);
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      readOnlySuggestedInstances = suggestedInstances.AsReadOnly();
-      // BackwardsCompatibility3.3
-      #region Backwards compatible code, remove with trunk integration
-      if (oldBackwardsCompatible != null) solutionPool = new CheckedItemList<IScope>(solutionPool);
-      else if (solutionPool == null) solutionPool = new CheckedItemList<IScope>();
-      #endregion
-      RegisterEventHandlers();
-    }
-
-    private void RegisterEventHandlers() {
-      problem.ProblemChanged += ProblemOnProblemChanged;
-      runs.CollectionReset += InformationChanged;
-      runs.ItemsAdded += InformationChanged;
-      runs.ItemsRemoved += InformationChanged;
-      runs.Reset += InformationChanged;
-      runs.UpdateOfRunsInProgressChanged += InformationChanged;
-      knowledgeBase.CollectionReset += InformationChanged;
-      knowledgeBase.ItemsAdded += InformationChanged;
-      knowledgeBase.ItemsRemoved += InformationChanged;
-    }
-
-    private void InformationChanged(object sender, EventArgs e) {
-      var runCollection = sender as RunCollection;
-      if (runCollection != null && runCollection.UpdateOfRunsInProgress) return;
-      UpdateSuggestions();
-    }
-
-    public void UpdateInstanceProjection() {
-      currentInstance = null;
-      var filter = new HashSet<string>();
-
-      if (Problem.ProblemId != -1) {
-        currentInstance = new Run { Name = Problem.Name };
-        Problem.Problem.CollectParameterValues(currentInstance.Parameters);
-        foreach (var c in RunCreationClient.GetCharacteristicValues(Problem.ProblemId)) {
-          var key = "Characteristic." + c.Name;
-          currentInstance.Results.Add(key, RunCreationClient.Instance.ConvertToItem(c));
-          filter.Add(key);
-        }
-      }
-      // TODO: There is a problem with missing values that has to be solved
-      // The common set of characteristics among all problems may be too small to be useful
-      // It has to be decided somehow which problem instances to include in order to obtain the set of features that is expressive and available
-      var allCharacteristics = ProblemInstances.Select(x => new HashSet<string>(x.Results.Where(y => y.Key.StartsWith("Characteristic.", StringComparison.Ordinal)).Select(y => y.Key))).ToList();
-      var commonCharacteristics = filter.Count > 0 ? filter : allCharacteristics[0];
-      for (var i = 0; i < allCharacteristics.Count; i++)
-        commonCharacteristics.IntersectWith(allCharacteristics[i]);
-
-      if (commonCharacteristics.Count == 0) return;
-
-      var instances = new Dictionary<string, double[]>();
-      foreach (var i in ProblemInstances)
-        instances[i.Name] = i.Results.Where(x => commonCharacteristics.Contains(x.Key)).OrderBy(x => x.Key).Select(x => (double)((dynamic)x.Value).Value).ToArray();
-      if (currentInstance != null)
-        instances[currentInstance.Name] = currentInstance.Results.Where(x => commonCharacteristics.Contains(x.Key)).OrderBy(x => x.Key).Select(x => (double)((dynamic)x.Value).Value).ToArray();
-
-      var allValues = instances.SelectMany(x => x.Value).ToList();
-      var avg = allValues.Average();
-      var stdev = allValues.StandardDeviation();
-
-      // normalize characteristic values by transforming them to their z-score
-      foreach (var key in instances.Keys.ToList()) {
-        var arr = instances[key];
-        for (var i = 0; i < arr.Length; i++) {
-          arr[i] = (arr[i] - avg) / stdev;
-        }
-      }
-
-      var key2Idx = new BidirectionalDictionary<string, int>();
-      foreach (var kvp in instances.Select((k, i) => new { Index = i, Key = k.Key }))
-        key2Idx.Add(kvp.Key, kvp.Index);
-
-      #region MDS
-      Func<double[], double[], double> euclid = (a, b) => Math.Sqrt(a.Zip(b, (x, y) => (x - y)).Sum(x => x * x));
-      var num = instances.Count;
-      var matrix = new DoubleMatrix(num, num);
-      for (var i = 0; i < num - 1; i++) {
-        for (var j = i + 1; j < num; j++) {
-          matrix[i, j] = matrix[j, i] = euclid(instances[key2Idx.GetBySecond(i)], instances[key2Idx.GetBySecond(j)]);
-        }
-      }
-
-      var coords = MultidimensionalScaling.KruskalShepard(matrix);
-      #endregion
-      #region PCA
-      var ds = new double[instances.Count, commonCharacteristics.Count];
-      foreach (var instance in instances) {
-        var arr = instance.Value;
-        for (var feature = 0; feature < arr.Length; feature++)
-          ds[key2Idx.GetByFirst(instance.Key), feature] = arr[feature];
-      }
-
-      int info;
-      double[] s2;
-      double[,] v;
-      alglib.pcabuildbasis(ds, ds.GetLength(0), ds.GetLength(1), out info, out s2, out v);
-      #endregion
-
-      ProblemInstances.UpdateOfRunsInProgress = true;
-      try {
-        foreach (var instance in ProblemInstances) {
-          double x = 0, y = 0;
-          for (var feature = 0; feature < ds.GetLength(1); feature++) {
-            x += ds[key2Idx.GetByFirst(instance.Name), feature] * v[feature, 0];
-            y += ds[key2Idx.GetByFirst(instance.Name), feature] * v[feature, 1];
-          }
-
-          IItem item;
-          if (instance.Results.TryGetValue("Projection.PCA.X", out item)) {
-            ((DoubleValue)item).Value = x;
-          } else instance.Results.Add("Projection.PCA.X", new DoubleValue(x));
-          if (instance.Results.TryGetValue("Projection.PCA.Y", out item)) {
-            ((DoubleValue)item).Value = y;
-          } else instance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
-
-          if (instance.Results.TryGetValue("Projection.MDS.X", out item)) {
-            ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(instance.Name), 0];
-          } else instance.Results.Add("Projection.MDS.X", new DoubleValue(coords[key2Idx.GetByFirst(instance.Name), 0]));
-          if (instance.Results.TryGetValue("Projection.MDS.Y", out item)) {
-            ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(instance.Name), 1];
-          } else instance.Results.Add("Projection.MDS.Y", new DoubleValue(coords[key2Idx.GetByFirst(instance.Name), 1]));
-        }
-      } finally { ProblemInstances.UpdateOfRunsInProgress = false; }
-
-      if (currentInstance != null) {
-        double x = 0, y = 0;
-        for (var feature = 0; feature < ds.GetLength(1); feature++) {
-          x += ds[key2Idx.GetByFirst(currentInstance.Name), feature] * v[feature, 0];
-          y += ds[key2Idx.GetByFirst(currentInstance.Name), feature] * v[feature, 1];
-        }
-
-        IItem item;
-        if (currentInstance.Results.TryGetValue("Projection.PCA.X", out item)) {
-          ((DoubleValue)item).Value = x;
-        } else currentInstance.Results.Add("Projection.PCA.X", new DoubleValue(x));
-        if (currentInstance.Results.TryGetValue("Projection.PCA.Y", out item)) {
-          ((DoubleValue)item).Value = y;
-        } else currentInstance.Results.Add("Projection.PCA.Y", new DoubleValue(y));
-
-        if (currentInstance.Results.TryGetValue("Projection.MDS.X", out item)) {
-          ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(currentInstance.Name), 0];
-        } else currentInstance.Results.Add("Projection.MDS.X", new DoubleValue(coords[key2Idx.GetByFirst(currentInstance.Name), 0]));
-        if (currentInstance.Results.TryGetValue("Projection.MDS.Y", out item)) {
-          ((DoubleValue)item).Value = coords[key2Idx.GetByFirst(currentInstance.Name), 1];
-        } else currentInstance.Results.Add("Projection.MDS.Y", new DoubleValue(coords[key2Idx.GetByFirst(currentInstance.Name), 1]));
-      }
-    }
-
-    public Tuple<double, double> ProjectCurrentInstance(string projection) {
-      if (currentInstance == null) return null;
-      var xKey = "Projection." + projection + ".X";
-      var yKey = "Projection." + projection + ".Y";
-      if (!currentInstance.Results.ContainsKey(xKey) || !currentInstance.Results.ContainsKey(yKey))
-        return null;
-      var x = ((DoubleValue)currentInstance.Results[xKey]).Value;
-      var y = ((DoubleValue)currentInstance.Results[yKey]).Value;
-      return Tuple.Create(x, y);
-    }
-
-    private static readonly HashSet<string> InterestingValueNames = new HashSet<string>() {
-      "QualityPerEvaluations", "Problem Name", "Problem Type", "Algorithm Name", "Algorithm Type", "Maximization", "BestKnownQuality"
-    };
-
-    public async void StartAlgorithmAsync(int index) {
-      var selectedInstance = suggestedInstances[index];
-      var algorithm = (IAlgorithm)selectedInstance.Clone();
-      algorithm.Prepare(true);
-      IParameter stopParam;
-      var monitorStop = true;
-      if (algorithm.Parameters.TryGetValue("MaximumEvaluations", out stopParam)) {
-        var maxEvalParam = stopParam as IValueParameter<Data.IntValue>;
-        if (maxEvalParam != null) {
-          maxEvalParam.Value.Value = MaximumEvaluations;
-          monitorStop = false;
-        }
-      }
-      algorithm.ExecutionStateChanged += AlgorithmOnExecutionStateChanged;
-      algorithm.ExceptionOccurred += AlgorithmOnExceptionOccurred;
-      if (monitorStop) algorithm.ExecutionTimeChanged += AlgorithmOnExecutionTimeChanged;
-
-      algorithm.Start();
-    }
-
-    public void StartAlgorithm(int index) {
-      var selectedInstance = suggestedInstances[index];
-      var algorithm = (IAlgorithm)selectedInstance.Clone();
-      algorithm.Prepare(true);
-      IParameter stopParam;
-      var monitorStop = true;
-      if (algorithm.Parameters.TryGetValue("MaximumEvaluations", out stopParam)) {
-        var maxEvalParam = stopParam as IValueParameter<Data.IntValue>;
-        if (maxEvalParam != null) {
-          maxEvalParam.Value.Value = MaximumEvaluations;
-          monitorStop = false;
-        }
-      }
-      algorithm.ExecutionStateChanged += AlgorithmOnExecutionStateChanged;
-      algorithm.ExceptionOccurred += AlgorithmOnExceptionOccurred;
-      if (monitorStop) algorithm.ExecutionTimeChanged += AlgorithmOnExecutionTimeChanged;
-
-      using (algWh = new AutoResetEvent(false)) {
-        algorithm.Start();
-        algWh.WaitOne();
-      }
-      algWh = null;
-    }
-
-    private AutoResetEvent algWh;
-
-    private void AlgorithmOnExecutionStateChanged(object sender, EventArgs eventArgs) {
-      var alg = sender as IAlgorithm;
-      if (alg == null) return;
-      if (alg.ExecutionState == ExecutionState.Started) {
-        CurrentResult = alg.Results;
-      } else if (alg.ExecutionState == ExecutionState.Stopped) {
-        alg.ExecutionStateChanged -= AlgorithmOnExecutionStateChanged;
-        alg.ExceptionOccurred -= AlgorithmOnExceptionOccurred;
-        alg.ExecutionTimeChanged -= AlgorithmOnExecutionTimeChanged;
-        foreach (var solution in alg.Results.Where(x => x.Name.ToLower().Contains("solution")).Select(x => x.Value).OfType<IScope>()) {
-          solutionPool.Add(solution);
-        }
-        Runs.Add(alg.Runs.Last());
-        if (algWh != null) algWh.Set();
-      }
-    }
-
-    private void AlgorithmOnExceptionOccurred(object sender, EventArgs<Exception> eventArgs) {
-      var alg = sender as IAlgorithm;
-      if (alg == null) return;
-      alg.ExecutionStateChanged -= AlgorithmOnExecutionStateChanged;
-      alg.ExceptionOccurred -= AlgorithmOnExceptionOccurred;
-      alg.ExecutionTimeChanged -= AlgorithmOnExecutionTimeChanged;
-      if (algWh != null) algWh.Set();
-    }
-
-    private void AlgorithmOnExecutionTimeChanged(object sender, EventArgs eventArgs) {
-      var alg = sender as IAlgorithm;
-      if (alg == null) return;
-      IResult evalSolResult;
-      if (!alg.Results.TryGetValue("EvaluatedSolutions", out evalSolResult) || !(evalSolResult.Value is Data.IntValue)) return;
-      var evalSols = ((Data.IntValue)evalSolResult.Value).Value;
-      if (evalSols >= MaximumEvaluations) alg.Stop();
-    }
-
-    public async void UpdateKnowledgeBaseAsync(IProgress progress) {
-      progress.Start("Updating Knowledge Base from OKB");
-      await Task.Factory.StartNew(() => { DoUpdateKnowledgeBase(progress); }, TaskCreationOptions.LongRunning);
-    }
-
-    public void UpdateKnowledgeBase() {
-      DoUpdateKnowledgeBase(new Progress(string.Empty, ProgressState.Started));
-    }
-
-    private void DoUpdateKnowledgeBase(IProgress progress) {
-      var queryClient = Clients.OKB.Query.QueryClient.Instance;
-      var adminClient = Clients.OKB.Administration.AdministrationClient.Instance;
-      try {
-        progress.Status = "Downloading run information...";
-        progress.ProgressValue = 0;
-        // FIXME: How to tell if refresh is necessary?
-        queryClient.Refresh();
-        progress.ProgressValue = 0.5;
-        progress.Status = "Downloading algorithm and problem instance information...";
-        // FIXME: How to tell if refresh is necessary?
-        adminClient.Refresh();
-
-        var probInstance = adminClient.Problems.SingleOrDefault(x => x.Id == Problem.ProblemId);
-        if (probInstance == null) throw new InvalidOperationException("The chosen problem instance cannot be found in the OKB.");
-        var probClassId = probInstance.ProblemClassId;
-
-        var problemClassFilter = (Clients.OKB.Query.StringComparisonAvailableValuesFilter)queryClient.Filters.Single(x => x.Label == "Problem Class Name");
-        problemClassFilter.Value = adminClient.ProblemClasses.Single(x => x.Id == probClassId).Name;
-
-        progress.Status = "Downloading problem instances...";
-        progress.ProgressValue = 0;
-        var p = 0;
-        ProblemInstances.UpdateOfRunsInProgress = true;
-        ProblemInstances.Clear();
-        var totalProblems = adminClient.Problems.Count(x => x.ProblemClassId == probClassId);
-        foreach (var problInst in adminClient.Problems.Where(x => x.ProblemClassId == probClassId)) {
-          progress.Status = string.Format("Downloading problem {0} (okb-id: {1})....", problInst.Name, problInst.Id);
-          var data = Clients.OKB.Administration.AdministrationClient.GetProblemData(problInst.Id);
-          if (data != null) {
-            using (var stream = new MemoryStream(data)) {
-              try {
-                var prob = (IProblem)XmlParser.Deserialize<IContent>(stream);
-                var probRun = new Run() { Name = prob.Name };
-                prob.CollectParameterValues(probRun.Parameters);
-                probRun.Parameters["Problem Name"] = new StringValue(prob.Name);
-                probRun.Parameters["Problem Type"] = new StringValue(prob.GetType().Name);
-                progress.Status += Environment.NewLine + "Downloading characteristics...";
-                foreach (var v in RunCreationClient.GetCharacteristicValues(problInst.Id)) {
-                  probRun.Results.Add("Characteristic." + v.Name, RunCreationClient.Instance.ConvertToItem(v));
-                }
-                ProblemInstances.Add(probRun);
-              } catch { }
-              stream.Close();
-            }
-          }
-          p++;
-          progress.ProgressValue = p / (double)totalProblems;
-        }
-
-        algorithmId2AlgorithmInstanceMapping.Clear();
-        progress.Status = "Downloading algorithm instances...";
-        progress.ProgressValue = 0;
-        p = 0;
-        foreach (var algInst in adminClient.Algorithms) {
-          progress.Status = string.Format("Downloading algorithm {0} (okb-id: {1})...", algInst.Name, algInst.Id);
-          var data = Clients.OKB.Administration.AdministrationClient.GetAlgorithmData(algInst.Id);
-          if (data != null) {
-            using (var stream = new MemoryStream(data)) {
-              try {
-                var alg = (IAlgorithm)XmlParser.Deserialize<IContent>(stream);
-                algorithmId2AlgorithmInstanceMapping.Add(algInst.Id, alg);
-              } catch { }
-              stream.Close();
-            }
-          }
-          p++;
-          progress.ProgressValue = p / (double)adminClient.Algorithms.Count;
-        }
-
-        var interestingValues = queryClient.ValueNames.Where(x => InterestingValueNames.Contains(x.Name)).ToList();
-
-        progress.Status = "Obtaining number of runs...";
-        progress.ProgressValue = 0;
-        p = 0;
-        var count = queryClient.GetNumberOfRuns(problemClassFilter);
-        if (count == 0) return;
-        
-        var runIds = queryClient.GetRunIds(problemClassFilter).ToList();
-        var conversions = new List<Task>();
-        var runList = new List<IRun>();
-        while (p < count) {
-          var nextIds = runIds.Skip(p).Take(500).ToList();
-          progress.Status = string.Format("Downloading runs {0} to {1} of {2}...", p, p + nextIds.Count, count);
-          var okbRuns = queryClient.GetRunsWithValues(nextIds, true, interestingValues);
-          conversions.Add(Task.Factory.StartNew(() => {
-            var hlRuns = okbRuns.AsParallel().Select(x => new { AlgorithmId = x.Algorithm.Id, Run = queryClient.ConvertToOptimizationRun(x) }).ToList();
-            lock (runList) {
-              foreach (var r in hlRuns) {
-                algorithmId2RunMapping.Add(r.AlgorithmId, r.Run);
-                runList.Add(r.Run);
-              }
-            }
-          }));
-          p += nextIds.Count;
-          progress.ProgressValue = p / (double)count;
-        }
-        Task.WaitAll(conversions.ToArray());
-
-        progress.Status = "Finishing...";
-        var algInstRunDict = runList.Where(x => x.Parameters.ContainsKey("Problem Name") && x.Parameters["Problem Name"] is StringValue)
-                                          .GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value)
-                                          .ToDictionary(x => x.Key, x => x.GroupBy(y => ((StringValue)y.Parameters["Algorithm Name"]).Value)
-                                                                                  .ToDictionary(y => y.Key, y => y.ToList()));
-
-        foreach (var instance in ProblemInstances) {
-          IItem probNameParam;
-          if (!instance.Parameters.TryGetValue("Problem Name", out probNameParam)) continue;
-
-          var probInstanceName = ((StringValue)probNameParam).Value;
-          var maximization = ((BoolValue)instance.Parameters["Maximization"]).Value;
-          
-          IItem bkParam;
-          if (!instance.Parameters.TryGetValue("BestKnownQuality", out bkParam) || !(bkParam is DoubleValue)) {
-            Dictionary<string, List<IRun>> algRuns;
-            if (!algInstRunDict.TryGetValue(probInstanceName, out algRuns)) continue;
-            var list = algRuns.SelectMany(x => x.Value)
-                              .Where(x => x.Results.ContainsKey("QualityPerEvaluations"))
-                              .Select(x => ((IndexedDataTable<double>)x.Results["QualityPerEvaluations"]).Rows.First().Values.Last().Item2);
-            bkParam = new DoubleValue(maximization ? list.Max() : list.Min());
-            instance.Parameters["BestKnownQuality"] = bkParam;
-          } else bkParam = instance.Parameters["BestKnownQuality"];
-
-          var bkQuality = ((DoubleValue)bkParam).Value;
-
-          if (!algInstRunDict.ContainsKey(probInstanceName)) continue;
-          foreach (var kvp in algInstRunDict[probInstanceName]) {
-            // TODO: Things needs to be configurable here (table name, targets)
-            foreach (var target in new[] { 1, 1.01, 1.05, 1.1, 1.2, 1.5 }) {
-              var result = ExpectedRuntimeHelper.CalculateErt(kvp.Value, "QualityPerEvaluations", bkQuality * target, maximization);
-              var resultName = kvp.Key + "@" + ((target - 1) * 100) + "%";
-              IItem item;
-              if (instance.Results.TryGetValue(resultName, out item)) {
-                ((DoubleValue)item).Value = Math.Log10(result.ExpectedRuntime);
-              } else instance.Results.Add(resultName, new DoubleValue(Math.Log10(result.ExpectedRuntime)));
-            }
-          }
-        }
-        KnowledgeBase = new RunCollection(runList);
-      } finally { progress.Finish(); ProblemInstances.UpdateOfRunsInProgress = false; }
-    }
-
-    private void UpdateSuggestions() {
-      if (Problem == null) return;
-      var instances = new SortedList<double, IAlgorithm>();
-      foreach (var relevantRuns in knowledgeBase.GroupBy(x => algorithmId2RunMapping.GetBySecond(x).Single())) {
-        var algorithm = algorithmId2AlgorithmInstanceMapping.GetByFirst(relevantRuns.Key);
-        var avgQuality = 0.0;
-        var counter = 0;
-        foreach (var problemRuns in relevantRuns.GroupBy(x => ((StringValue)x.Parameters["Problem Name"]).Value)) {
-          var probInstance = ProblemInstances.SingleOrDefault(x => x.Name == problemRuns.Key);
-          if (probInstance == null) continue;
-          var bkQuality = ((DoubleValue)probInstance.Parameters["BestKnownQuality"]).Value;
-          foreach (var run in problemRuns) {
-            var performanceGraph = ((IndexedDataTable<double>)run.Results["QualityPerEvaluations"]);
-            try {
-              avgQuality += performanceGraph.Rows.First().Values.TakeWhile(x => x.Item1 < MaximumEvaluations).Last().Item2 / bkQuality;
-              counter++;
-            } catch {
-              continue;
-            }
-          }
-        }
-        avgQuality /= counter;
-        instances.Add(avgQuality, algorithm);
-      }
-
-      suggestedInstances.Clear();
-      var instanceLadder = instances.Select(x => (IAlgorithm)x.Value.Clone()).ToList();
-      if (Maximization) instanceLadder.Reverse();
-      suggestedInstances.AddRange(instanceLadder);
-    }
-
-    public event PropertyChangedEventHandler PropertyChanged;
-    private void OnPropertyChanged(string propertyName) {
-      var handler = PropertyChanged;
-      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
-    }
-  }
-}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.Designer.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.Designer.cs	(revision 13667)
@@ -0,0 +1,781 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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
+
+namespace HeuristicLab.OptimizationExpertSystem {
+  partial class ExpertSystemView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    #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();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      this.evaluationsLimitabel = new System.Windows.Forms.Label();
+      this.maxEvaluationsTextBox = new System.Windows.Forms.TextBox();
+      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
+      this.problemTabPage = new System.Windows.Forms.TabPage();
+      this.problemViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.algorithmTabPage = new System.Windows.Forms.TabPage();
+      this.algorithmStartButton = new System.Windows.Forms.Button();
+      this.algorithmViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.algorithmSuggestionLabel = new System.Windows.Forms.Label();
+      this.suggestedInstancesComboBox = new System.Windows.Forms.ComboBox();
+      this.runsTabPage = new System.Windows.Forms.TabPage();
+      this.runsView = new HeuristicLab.Optimization.Views.RunCollectionView();
+      this.solutionsTabPage = new System.Windows.Forms.TabPage();
+      this.qualityNameLabel = new System.Windows.Forms.Label();
+      this.solutionDiversitySimilarityLabel = new System.Windows.Forms.Label();
+      this.solutionNameLabel = new System.Windows.Forms.Label();
+      this.similarityComboBox = new System.Windows.Forms.ComboBox();
+      this.qualityNameComboBox = new System.Windows.Forms.ComboBox();
+      this.solutionNameComboBox = new System.Windows.Forms.ComboBox();
+      this.solutionsTabControl = new System.Windows.Forms.TabControl();
+      this.solutionsListTabPage = new System.Windows.Forms.TabPage();
+      this.solutionsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.solutionsQualityTabPage = new System.Windows.Forms.TabPage();
+      this.solutionsQualityViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.solutionsDiversityTabPage = new System.Windows.Forms.TabPage();
+      this.solutionsDiversityViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.solutionsLengthScaleTabPage = new System.Windows.Forms.TabPage();
+      this.solutionsLengthScaleViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.solutionsNetworkTabPage = new System.Windows.Forms.TabPage();
+      this.solutionsNetworkViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.okbTabPage = new System.Windows.Forms.TabPage();
+      this.kbViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.problemInstancesTabPage = new System.Windows.Forms.TabPage();
+      this.label1 = new System.Windows.Forms.Label();
+      this.projectionComboBox = new System.Windows.Forms.ComboBox();
+      this.problemInstancesTabControl = new System.Windows.Forms.TabControl();
+      this.instancesTabPage = new System.Windows.Forms.TabPage();
+      this.problemInstancesView = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.mapTabPage = new System.Windows.Forms.TabPage();
+      this.instanceMapChart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.refreshMapButton = new System.Windows.Forms.Button();
+      this.progressPanel = new System.Windows.Forms.Panel();
+      this.okbDownloadButton = new System.Windows.Forms.Button();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      this.solutionsFdcTabPage = new System.Windows.Forms.TabPage();
+      this.solutionsFdcViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.problemTabPage.SuspendLayout();
+      this.algorithmTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      this.solutionsTabPage.SuspendLayout();
+      this.solutionsTabControl.SuspendLayout();
+      this.solutionsListTabPage.SuspendLayout();
+      this.solutionsQualityTabPage.SuspendLayout();
+      this.solutionsDiversityTabPage.SuspendLayout();
+      this.solutionsLengthScaleTabPage.SuspendLayout();
+      this.solutionsNetworkTabPage.SuspendLayout();
+      this.okbTabPage.SuspendLayout();
+      this.problemInstancesTabPage.SuspendLayout();
+      this.problemInstancesTabControl.SuspendLayout();
+      this.instancesTabPage.SuspendLayout();
+      this.mapTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.instanceMapChart)).BeginInit();
+      this.solutionsFdcTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(75, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(592, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(673, 3);
+      // 
+      // evaluationsLimitabel
+      // 
+      this.evaluationsLimitabel.AutoSize = true;
+      this.evaluationsLimitabel.Location = new System.Drawing.Point(3, 29);
+      this.evaluationsLimitabel.Name = "evaluationsLimitabel";
+      this.evaluationsLimitabel.Size = new System.Drawing.Size(66, 13);
+      this.evaluationsLimitabel.TabIndex = 5;
+      this.evaluationsLimitabel.Text = "Budget (FE):";
+      // 
+      // maxEvaluationsTextBox
+      // 
+      this.maxEvaluationsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.maxEvaluationsTextBox.Location = new System.Drawing.Point(75, 26);
+      this.maxEvaluationsTextBox.Name = "maxEvaluationsTextBox";
+      this.maxEvaluationsTextBox.Size = new System.Drawing.Size(592, 20);
+      this.maxEvaluationsTextBox.TabIndex = 6;
+      this.maxEvaluationsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.MaxEvaluationsTextBoxOnValidating);
+      // 
+      // tabControl
+      // 
+      this.tabControl.AllowDrop = true;
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Controls.Add(this.problemTabPage);
+      this.tabControl.Controls.Add(this.algorithmTabPage);
+      this.tabControl.Controls.Add(this.runsTabPage);
+      this.tabControl.Controls.Add(this.solutionsTabPage);
+      this.tabControl.Controls.Add(this.okbTabPage);
+      this.tabControl.Controls.Add(this.problemInstancesTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 81);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(689, 454);
+      this.tabControl.TabIndex = 17;
+      // 
+      // problemTabPage
+      // 
+      this.problemTabPage.AllowDrop = true;
+      this.problemTabPage.Controls.Add(this.problemViewHost);
+      this.problemTabPage.Location = new System.Drawing.Point(4, 22);
+      this.problemTabPage.Name = "problemTabPage";
+      this.problemTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.problemTabPage.Size = new System.Drawing.Size(681, 428);
+      this.problemTabPage.TabIndex = 1;
+      this.problemTabPage.Text = "Problem";
+      this.problemTabPage.UseVisualStyleBackColor = true;
+      // 
+      // problemViewHost
+      // 
+      this.problemViewHost.Caption = "View";
+      this.problemViewHost.Content = null;
+      this.problemViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.problemViewHost.Enabled = false;
+      this.problemViewHost.Location = new System.Drawing.Point(3, 3);
+      this.problemViewHost.Name = "problemViewHost";
+      this.problemViewHost.ReadOnly = false;
+      this.problemViewHost.Size = new System.Drawing.Size(675, 422);
+      this.problemViewHost.TabIndex = 2;
+      this.problemViewHost.ViewsLabelVisible = false;
+      this.problemViewHost.ViewType = null;
+      // 
+      // algorithmTabPage
+      // 
+      this.algorithmTabPage.Controls.Add(this.algorithmStartButton);
+      this.algorithmTabPage.Controls.Add(this.algorithmViewHost);
+      this.algorithmTabPage.Controls.Add(this.algorithmSuggestionLabel);
+      this.algorithmTabPage.Controls.Add(this.suggestedInstancesComboBox);
+      this.algorithmTabPage.Location = new System.Drawing.Point(4, 22);
+      this.algorithmTabPage.Name = "algorithmTabPage";
+      this.algorithmTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.algorithmTabPage.Size = new System.Drawing.Size(681, 428);
+      this.algorithmTabPage.TabIndex = 4;
+      this.algorithmTabPage.Text = "Algorithm";
+      this.algorithmTabPage.UseVisualStyleBackColor = true;
+      // 
+      // algorithmStartButton
+      // 
+      this.algorithmStartButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmStartButton.Location = new System.Drawing.Point(649, 5);
+      this.algorithmStartButton.Name = "algorithmStartButton";
+      this.algorithmStartButton.Size = new System.Drawing.Size(26, 23);
+      this.algorithmStartButton.TabIndex = 3;
+      this.algorithmStartButton.Text = "Start";
+      this.algorithmStartButton.UseVisualStyleBackColor = true;
+      this.algorithmStartButton.Click += new System.EventHandler(this.AlgorithmStartButtonOnClick);
+      // 
+      // algorithmViewHost
+      // 
+      this.algorithmViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmViewHost.Caption = "View";
+      this.algorithmViewHost.Content = null;
+      this.algorithmViewHost.Enabled = false;
+      this.algorithmViewHost.Location = new System.Drawing.Point(6, 36);
+      this.algorithmViewHost.Name = "algorithmViewHost";
+      this.algorithmViewHost.ReadOnly = false;
+      this.algorithmViewHost.Size = new System.Drawing.Size(669, 386);
+      this.algorithmViewHost.TabIndex = 2;
+      this.algorithmViewHost.ViewsLabelVisible = true;
+      this.algorithmViewHost.ViewType = null;
+      // 
+      // algorithmSuggestionLabel
+      // 
+      this.algorithmSuggestionLabel.AutoSize = true;
+      this.algorithmSuggestionLabel.Location = new System.Drawing.Point(6, 9);
+      this.algorithmSuggestionLabel.Name = "algorithmSuggestionLabel";
+      this.algorithmSuggestionLabel.Size = new System.Drawing.Size(156, 13);
+      this.algorithmSuggestionLabel.TabIndex = 1;
+      this.algorithmSuggestionLabel.Text = "Suggested Algorithm Instances:";
+      // 
+      // suggestedInstancesComboBox
+      // 
+      this.suggestedInstancesComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.suggestedInstancesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.suggestedInstancesComboBox.FormattingEnabled = true;
+      this.suggestedInstancesComboBox.Location = new System.Drawing.Point(178, 6);
+      this.suggestedInstancesComboBox.Name = "suggestedInstancesComboBox";
+      this.suggestedInstancesComboBox.Size = new System.Drawing.Size(465, 21);
+      this.suggestedInstancesComboBox.TabIndex = 0;
+      this.suggestedInstancesComboBox.SelectedIndexChanged += new System.EventHandler(this.SuggestedInstancesComboBoxOnSelectedIndexChanged);
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Controls.Add(this.runsView);
+      this.runsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.runsTabPage.Name = "runsTabPage";
+      this.runsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.runsTabPage.Size = new System.Drawing.Size(681, 428);
+      this.runsTabPage.TabIndex = 3;
+      this.runsTabPage.Text = "Runs";
+      this.runsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // runsView
+      // 
+      this.runsView.Caption = "RunCollection View";
+      this.runsView.Content = null;
+      this.runsView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.runsView.Location = new System.Drawing.Point(3, 3);
+      this.runsView.Name = "runsView";
+      this.runsView.ReadOnly = false;
+      this.runsView.Size = new System.Drawing.Size(675, 422);
+      this.runsView.TabIndex = 1;
+      // 
+      // solutionsTabPage
+      // 
+      this.solutionsTabPage.Controls.Add(this.qualityNameLabel);
+      this.solutionsTabPage.Controls.Add(this.solutionDiversitySimilarityLabel);
+      this.solutionsTabPage.Controls.Add(this.solutionNameLabel);
+      this.solutionsTabPage.Controls.Add(this.similarityComboBox);
+      this.solutionsTabPage.Controls.Add(this.qualityNameComboBox);
+      this.solutionsTabPage.Controls.Add(this.solutionNameComboBox);
+      this.solutionsTabPage.Controls.Add(this.solutionsTabControl);
+      this.solutionsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.solutionsTabPage.Name = "solutionsTabPage";
+      this.solutionsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.solutionsTabPage.Size = new System.Drawing.Size(681, 428);
+      this.solutionsTabPage.TabIndex = 7;
+      this.solutionsTabPage.Text = "Solutions";
+      this.solutionsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // qualityNameLabel
+      // 
+      this.qualityNameLabel.AutoSize = true;
+      this.qualityNameLabel.Location = new System.Drawing.Point(227, 9);
+      this.qualityNameLabel.Name = "qualityNameLabel";
+      this.qualityNameLabel.Size = new System.Drawing.Size(42, 13);
+      this.qualityNameLabel.TabIndex = 2;
+      this.qualityNameLabel.Text = "Quality:";
+      // 
+      // solutionDiversitySimilarityLabel
+      // 
+      this.solutionDiversitySimilarityLabel.AutoSize = true;
+      this.solutionDiversitySimilarityLabel.Location = new System.Drawing.Point(449, 9);
+      this.solutionDiversitySimilarityLabel.Name = "solutionDiversitySimilarityLabel";
+      this.solutionDiversitySimilarityLabel.Size = new System.Drawing.Size(50, 13);
+      this.solutionDiversitySimilarityLabel.TabIndex = 2;
+      this.solutionDiversitySimilarityLabel.Text = "Similarity:";
+      // 
+      // solutionNameLabel
+      // 
+      this.solutionNameLabel.AutoSize = true;
+      this.solutionNameLabel.Location = new System.Drawing.Point(6, 9);
+      this.solutionNameLabel.Name = "solutionNameLabel";
+      this.solutionNameLabel.Size = new System.Drawing.Size(48, 13);
+      this.solutionNameLabel.TabIndex = 2;
+      this.solutionNameLabel.Text = "Solution:";
+      // 
+      // similarityComboBox
+      // 
+      this.similarityComboBox.DisplayMember = "ItemName";
+      this.similarityComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.similarityComboBox.FormattingEnabled = true;
+      this.similarityComboBox.Location = new System.Drawing.Point(505, 6);
+      this.similarityComboBox.Name = "similarityComboBox";
+      this.similarityComboBox.Size = new System.Drawing.Size(150, 21);
+      this.similarityComboBox.TabIndex = 1;
+      this.similarityComboBox.SelectedIndexChanged += new System.EventHandler(this.similarityComboBox_SelectedIndexChanged);
+      // 
+      // qualityNameComboBox
+      // 
+      this.qualityNameComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.qualityNameComboBox.FormattingEnabled = true;
+      this.qualityNameComboBox.Location = new System.Drawing.Point(281, 6);
+      this.qualityNameComboBox.Name = "qualityNameComboBox";
+      this.qualityNameComboBox.Size = new System.Drawing.Size(150, 21);
+      this.qualityNameComboBox.TabIndex = 1;
+      this.qualityNameComboBox.SelectedIndexChanged += new System.EventHandler(this.qualityNameComboBox_SelectedIndexChanged);
+      // 
+      // solutionNameComboBox
+      // 
+      this.solutionNameComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.solutionNameComboBox.FormattingEnabled = true;
+      this.solutionNameComboBox.Location = new System.Drawing.Point(60, 6);
+      this.solutionNameComboBox.Name = "solutionNameComboBox";
+      this.solutionNameComboBox.Size = new System.Drawing.Size(150, 21);
+      this.solutionNameComboBox.TabIndex = 1;
+      this.solutionNameComboBox.SelectedIndexChanged += new System.EventHandler(this.solutionNameComboBox_SelectedIndexChanged);
+      // 
+      // solutionsTabControl
+      // 
+      this.solutionsTabControl.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.solutionsTabControl.Controls.Add(this.solutionsListTabPage);
+      this.solutionsTabControl.Controls.Add(this.solutionsQualityTabPage);
+      this.solutionsTabControl.Controls.Add(this.solutionsDiversityTabPage);
+      this.solutionsTabControl.Controls.Add(this.solutionsFdcTabPage);
+      this.solutionsTabControl.Controls.Add(this.solutionsLengthScaleTabPage);
+      this.solutionsTabControl.Controls.Add(this.solutionsNetworkTabPage);
+      this.solutionsTabControl.Location = new System.Drawing.Point(3, 33);
+      this.solutionsTabControl.Name = "solutionsTabControl";
+      this.solutionsTabControl.SelectedIndex = 0;
+      this.solutionsTabControl.Size = new System.Drawing.Size(675, 392);
+      this.solutionsTabControl.TabIndex = 0;
+      // 
+      // solutionsListTabPage
+      // 
+      this.solutionsListTabPage.Controls.Add(this.solutionsViewHost);
+      this.solutionsListTabPage.Location = new System.Drawing.Point(4, 22);
+      this.solutionsListTabPage.Name = "solutionsListTabPage";
+      this.solutionsListTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.solutionsListTabPage.Size = new System.Drawing.Size(667, 366);
+      this.solutionsListTabPage.TabIndex = 0;
+      this.solutionsListTabPage.Text = "List";
+      this.solutionsListTabPage.UseVisualStyleBackColor = true;
+      // 
+      // solutionsViewHost
+      // 
+      this.solutionsViewHost.Caption = "View";
+      this.solutionsViewHost.Content = null;
+      this.solutionsViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.solutionsViewHost.Enabled = false;
+      this.solutionsViewHost.Location = new System.Drawing.Point(3, 3);
+      this.solutionsViewHost.Name = "solutionsViewHost";
+      this.solutionsViewHost.ReadOnly = false;
+      this.solutionsViewHost.Size = new System.Drawing.Size(661, 360);
+      this.solutionsViewHost.TabIndex = 0;
+      this.solutionsViewHost.ViewsLabelVisible = true;
+      this.solutionsViewHost.ViewType = null;
+      // 
+      // solutionsQualityTabPage
+      // 
+      this.solutionsQualityTabPage.Controls.Add(this.solutionsQualityViewHost);
+      this.solutionsQualityTabPage.Location = new System.Drawing.Point(4, 22);
+      this.solutionsQualityTabPage.Name = "solutionsQualityTabPage";
+      this.solutionsQualityTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.solutionsQualityTabPage.Size = new System.Drawing.Size(667, 366);
+      this.solutionsQualityTabPage.TabIndex = 1;
+      this.solutionsQualityTabPage.Text = "Quality Analysis";
+      this.solutionsQualityTabPage.UseVisualStyleBackColor = true;
+      // 
+      // solutionsQualityViewHost
+      // 
+      this.solutionsQualityViewHost.Caption = "View";
+      this.solutionsQualityViewHost.Content = null;
+      this.solutionsQualityViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.solutionsQualityViewHost.Enabled = false;
+      this.solutionsQualityViewHost.Location = new System.Drawing.Point(3, 3);
+      this.solutionsQualityViewHost.Name = "solutionsQualityViewHost";
+      this.solutionsQualityViewHost.ReadOnly = false;
+      this.solutionsQualityViewHost.Size = new System.Drawing.Size(661, 360);
+      this.solutionsQualityViewHost.TabIndex = 0;
+      this.solutionsQualityViewHost.ViewsLabelVisible = true;
+      this.solutionsQualityViewHost.ViewType = null;
+      // 
+      // solutionsDiversityTabPage
+      // 
+      this.solutionsDiversityTabPage.Controls.Add(this.solutionsDiversityViewHost);
+      this.solutionsDiversityTabPage.Location = new System.Drawing.Point(4, 22);
+      this.solutionsDiversityTabPage.Name = "solutionsDiversityTabPage";
+      this.solutionsDiversityTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.solutionsDiversityTabPage.Size = new System.Drawing.Size(667, 366);
+      this.solutionsDiversityTabPage.TabIndex = 2;
+      this.solutionsDiversityTabPage.Text = "Diversity Analysis";
+      this.solutionsDiversityTabPage.UseVisualStyleBackColor = true;
+      // 
+      // solutionsDiversityViewHost
+      // 
+      this.solutionsDiversityViewHost.Caption = "View";
+      this.solutionsDiversityViewHost.Content = null;
+      this.solutionsDiversityViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.solutionsDiversityViewHost.Enabled = false;
+      this.solutionsDiversityViewHost.Location = new System.Drawing.Point(3, 3);
+      this.solutionsDiversityViewHost.Name = "solutionsDiversityViewHost";
+      this.solutionsDiversityViewHost.ReadOnly = false;
+      this.solutionsDiversityViewHost.Size = new System.Drawing.Size(661, 360);
+      this.solutionsDiversityViewHost.TabIndex = 1;
+      this.solutionsDiversityViewHost.ViewsLabelVisible = true;
+      this.solutionsDiversityViewHost.ViewType = null;
+      // 
+      // solutionsLengthScaleTabPage
+      // 
+      this.solutionsLengthScaleTabPage.Controls.Add(this.solutionsLengthScaleViewHost);
+      this.solutionsLengthScaleTabPage.Location = new System.Drawing.Point(4, 22);
+      this.solutionsLengthScaleTabPage.Name = "solutionsLengthScaleTabPage";
+      this.solutionsLengthScaleTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.solutionsLengthScaleTabPage.Size = new System.Drawing.Size(667, 366);
+      this.solutionsLengthScaleTabPage.TabIndex = 3;
+      this.solutionsLengthScaleTabPage.Text = "Length-Scale Analysis";
+      this.solutionsLengthScaleTabPage.UseVisualStyleBackColor = true;
+      // 
+      // solutionsLengthScaleViewHost
+      // 
+      this.solutionsLengthScaleViewHost.Caption = "View";
+      this.solutionsLengthScaleViewHost.Content = null;
+      this.solutionsLengthScaleViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.solutionsLengthScaleViewHost.Enabled = false;
+      this.solutionsLengthScaleViewHost.Location = new System.Drawing.Point(3, 3);
+      this.solutionsLengthScaleViewHost.Name = "solutionsLengthScaleViewHost";
+      this.solutionsLengthScaleViewHost.ReadOnly = false;
+      this.solutionsLengthScaleViewHost.Size = new System.Drawing.Size(661, 360);
+      this.solutionsLengthScaleViewHost.TabIndex = 0;
+      this.solutionsLengthScaleViewHost.ViewsLabelVisible = true;
+      this.solutionsLengthScaleViewHost.ViewType = null;
+      // 
+      // solutionsNetworkTabPage
+      // 
+      this.solutionsNetworkTabPage.Controls.Add(this.solutionsNetworkViewHost);
+      this.solutionsNetworkTabPage.Location = new System.Drawing.Point(4, 22);
+      this.solutionsNetworkTabPage.Name = "solutionsNetworkTabPage";
+      this.solutionsNetworkTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.solutionsNetworkTabPage.Size = new System.Drawing.Size(667, 366);
+      this.solutionsNetworkTabPage.TabIndex = 4;
+      this.solutionsNetworkTabPage.Text = "Network Analysis";
+      this.solutionsNetworkTabPage.UseVisualStyleBackColor = true;
+      // 
+      // solutionsNetworkViewHost
+      // 
+      this.solutionsNetworkViewHost.Caption = "View";
+      this.solutionsNetworkViewHost.Content = null;
+      this.solutionsNetworkViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.solutionsNetworkViewHost.Enabled = false;
+      this.solutionsNetworkViewHost.Location = new System.Drawing.Point(3, 3);
+      this.solutionsNetworkViewHost.Name = "solutionsNetworkViewHost";
+      this.solutionsNetworkViewHost.ReadOnly = false;
+      this.solutionsNetworkViewHost.Size = new System.Drawing.Size(661, 360);
+      this.solutionsNetworkViewHost.TabIndex = 0;
+      this.solutionsNetworkViewHost.ViewsLabelVisible = true;
+      this.solutionsNetworkViewHost.ViewType = null;
+      // 
+      // okbTabPage
+      // 
+      this.okbTabPage.Controls.Add(this.kbViewHost);
+      this.okbTabPage.Location = new System.Drawing.Point(4, 22);
+      this.okbTabPage.Name = "okbTabPage";
+      this.okbTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.okbTabPage.Size = new System.Drawing.Size(681, 428);
+      this.okbTabPage.TabIndex = 5;
+      this.okbTabPage.Text = "Knowledge Base";
+      this.okbTabPage.UseVisualStyleBackColor = true;
+      // 
+      // kbViewHost
+      // 
+      this.kbViewHost.Caption = "View";
+      this.kbViewHost.Content = null;
+      this.kbViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.kbViewHost.Enabled = false;
+      this.kbViewHost.Location = new System.Drawing.Point(3, 3);
+      this.kbViewHost.Name = "kbViewHost";
+      this.kbViewHost.ReadOnly = true;
+      this.kbViewHost.Size = new System.Drawing.Size(675, 422);
+      this.kbViewHost.TabIndex = 3;
+      this.kbViewHost.ViewsLabelVisible = true;
+      this.kbViewHost.ViewType = null;
+      // 
+      // problemInstancesTabPage
+      // 
+      this.problemInstancesTabPage.Controls.Add(this.label1);
+      this.problemInstancesTabPage.Controls.Add(this.projectionComboBox);
+      this.problemInstancesTabPage.Controls.Add(this.problemInstancesTabControl);
+      this.problemInstancesTabPage.Controls.Add(this.refreshMapButton);
+      this.problemInstancesTabPage.Location = new System.Drawing.Point(4, 22);
+      this.problemInstancesTabPage.Name = "problemInstancesTabPage";
+      this.problemInstancesTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.problemInstancesTabPage.Size = new System.Drawing.Size(681, 428);
+      this.problemInstancesTabPage.TabIndex = 6;
+      this.problemInstancesTabPage.Text = "Problem Instances";
+      this.problemInstancesTabPage.UseVisualStyleBackColor = true;
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(35, 11);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(57, 13);
+      this.label1.TabIndex = 6;
+      this.label1.Text = "Projection:";
+      // 
+      // projectionComboBox
+      // 
+      this.projectionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.projectionComboBox.FormattingEnabled = true;
+      this.projectionComboBox.Location = new System.Drawing.Point(98, 8);
+      this.projectionComboBox.Name = "projectionComboBox";
+      this.projectionComboBox.Size = new System.Drawing.Size(158, 21);
+      this.projectionComboBox.TabIndex = 5;
+      this.projectionComboBox.SelectedIndexChanged += new System.EventHandler(this.ProjectionComboBoxOnSelectedIndexChanged);
+      // 
+      // problemInstancesTabControl
+      // 
+      this.problemInstancesTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.problemInstancesTabControl.Controls.Add(this.instancesTabPage);
+      this.problemInstancesTabControl.Controls.Add(this.mapTabPage);
+      this.problemInstancesTabControl.Location = new System.Drawing.Point(3, 35);
+      this.problemInstancesTabControl.Name = "problemInstancesTabControl";
+      this.problemInstancesTabControl.SelectedIndex = 0;
+      this.problemInstancesTabControl.Size = new System.Drawing.Size(675, 390);
+      this.problemInstancesTabControl.TabIndex = 4;
+      // 
+      // instancesTabPage
+      // 
+      this.instancesTabPage.Controls.Add(this.problemInstancesView);
+      this.instancesTabPage.Location = new System.Drawing.Point(4, 22);
+      this.instancesTabPage.Name = "instancesTabPage";
+      this.instancesTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.instancesTabPage.Size = new System.Drawing.Size(667, 364);
+      this.instancesTabPage.TabIndex = 0;
+      this.instancesTabPage.Text = "Instances";
+      this.instancesTabPage.UseVisualStyleBackColor = true;
+      // 
+      // problemInstancesView
+      // 
+      this.problemInstancesView.Caption = "View";
+      this.problemInstancesView.Content = null;
+      this.problemInstancesView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.problemInstancesView.Enabled = false;
+      this.problemInstancesView.Location = new System.Drawing.Point(3, 3);
+      this.problemInstancesView.Name = "problemInstancesView";
+      this.problemInstancesView.ReadOnly = false;
+      this.problemInstancesView.Size = new System.Drawing.Size(661, 358);
+      this.problemInstancesView.TabIndex = 0;
+      this.problemInstancesView.ViewsLabelVisible = true;
+      this.problemInstancesView.ViewType = null;
+      // 
+      // mapTabPage
+      // 
+      this.mapTabPage.Controls.Add(this.instanceMapChart);
+      this.mapTabPage.Location = new System.Drawing.Point(4, 22);
+      this.mapTabPage.Name = "mapTabPage";
+      this.mapTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.mapTabPage.Size = new System.Drawing.Size(667, 364);
+      this.mapTabPage.TabIndex = 1;
+      this.mapTabPage.Text = "Map";
+      this.mapTabPage.UseVisualStyleBackColor = true;
+      // 
+      // instanceMapChart
+      // 
+      chartArea1.AxisX.MajorGrid.LineColor = System.Drawing.Color.LightGray;
+      chartArea1.AxisX.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea1.AxisY.MajorGrid.LineColor = System.Drawing.Color.LightGray;
+      chartArea1.AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea1.Name = "Default";
+      this.instanceMapChart.ChartAreas.Add(chartArea1);
+      this.instanceMapChart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Enabled = false;
+      legend1.Name = "Legend";
+      this.instanceMapChart.Legends.Add(legend1);
+      this.instanceMapChart.Location = new System.Drawing.Point(3, 3);
+      this.instanceMapChart.Name = "instanceMapChart";
+      series1.ChartArea = "Default";
+      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
+      series1.Legend = "Legend";
+      series1.MarkerSize = 10;
+      series1.Name = "InstancesSeries";
+      series2.ChartArea = "Default";
+      series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
+      series2.Legend = "Legend";
+      series2.MarkerColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
+      series2.MarkerSize = 15;
+      series2.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Cross;
+      series2.Name = "CurrentInstanceSeries";
+      this.instanceMapChart.Series.Add(series1);
+      this.instanceMapChart.Series.Add(series2);
+      this.instanceMapChart.Size = new System.Drawing.Size(661, 358);
+      this.instanceMapChart.TabIndex = 0;
+      // 
+      // refreshMapButton
+      // 
+      this.refreshMapButton.Location = new System.Drawing.Point(3, 6);
+      this.refreshMapButton.Name = "refreshMapButton";
+      this.refreshMapButton.Size = new System.Drawing.Size(26, 23);
+      this.refreshMapButton.TabIndex = 1;
+      this.refreshMapButton.Text = "Refresh";
+      this.refreshMapButton.UseVisualStyleBackColor = true;
+      this.refreshMapButton.Click += new System.EventHandler(this.RefreshMapButtonOnClick);
+      // 
+      // progressPanel
+      // 
+      this.progressPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.progressPanel.Location = new System.Drawing.Point(0, 81);
+      this.progressPanel.Name = "progressPanel";
+      this.progressPanel.Size = new System.Drawing.Size(692, 454);
+      this.progressPanel.TabIndex = 2;
+      this.progressPanel.Visible = false;
+      // 
+      // okbDownloadButton
+      // 
+      this.okbDownloadButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.okbDownloadButton.Location = new System.Drawing.Point(6, 52);
+      this.okbDownloadButton.Name = "okbDownloadButton";
+      this.okbDownloadButton.Size = new System.Drawing.Size(661, 23);
+      this.okbDownloadButton.TabIndex = 1;
+      this.okbDownloadButton.Text = "Download from OKB";
+      this.okbDownloadButton.UseVisualStyleBackColor = true;
+      this.okbDownloadButton.Click += new System.EventHandler(this.OkbDownloadButtonOnClick);
+      // 
+      // openFileDialog
+      // 
+      this.openFileDialog.DefaultExt = "hl";
+      this.openFileDialog.FileName = "Optimizer";
+      this.openFileDialog.Filter = "HeuristicLab Files|*.hl|All Files|*.*";
+      this.openFileDialog.Title = "Open Optimizer";
+      // 
+      // solutionsFdcTabPage
+      // 
+      this.solutionsFdcTabPage.Controls.Add(this.solutionsFdcViewHost);
+      this.solutionsFdcTabPage.Location = new System.Drawing.Point(4, 22);
+      this.solutionsFdcTabPage.Name = "solutionsFdcTabPage";
+      this.solutionsFdcTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.solutionsFdcTabPage.Size = new System.Drawing.Size(667, 366);
+      this.solutionsFdcTabPage.TabIndex = 5;
+      this.solutionsFdcTabPage.Text = "Fitness-Distance Analysis";
+      this.solutionsFdcTabPage.UseVisualStyleBackColor = true;
+      // 
+      // solutionsFdcViewHost
+      // 
+      this.solutionsFdcViewHost.Caption = "View";
+      this.solutionsFdcViewHost.Content = null;
+      this.solutionsFdcViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.solutionsFdcViewHost.Enabled = false;
+      this.solutionsFdcViewHost.Location = new System.Drawing.Point(3, 3);
+      this.solutionsFdcViewHost.Name = "solutionsFdcViewHost";
+      this.solutionsFdcViewHost.ReadOnly = false;
+      this.solutionsFdcViewHost.Size = new System.Drawing.Size(661, 360);
+      this.solutionsFdcViewHost.TabIndex = 0;
+      this.solutionsFdcViewHost.ViewsLabelVisible = true;
+      this.solutionsFdcViewHost.ViewType = null;
+      // 
+      // ExpertSystemView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.okbDownloadButton);
+      this.Controls.Add(this.tabControl);
+      this.Controls.Add(this.evaluationsLimitabel);
+      this.Controls.Add(this.maxEvaluationsTextBox);
+      this.Controls.Add(this.progressPanel);
+      this.Name = "ExpertSystemView";
+      this.Size = new System.Drawing.Size(692, 535);
+      this.Controls.SetChildIndex(this.progressPanel, 0);
+      this.Controls.SetChildIndex(this.maxEvaluationsTextBox, 0);
+      this.Controls.SetChildIndex(this.evaluationsLimitabel, 0);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.okbDownloadButton, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.problemTabPage.ResumeLayout(false);
+      this.algorithmTabPage.ResumeLayout(false);
+      this.algorithmTabPage.PerformLayout();
+      this.runsTabPage.ResumeLayout(false);
+      this.solutionsTabPage.ResumeLayout(false);
+      this.solutionsTabPage.PerformLayout();
+      this.solutionsTabControl.ResumeLayout(false);
+      this.solutionsListTabPage.ResumeLayout(false);
+      this.solutionsQualityTabPage.ResumeLayout(false);
+      this.solutionsDiversityTabPage.ResumeLayout(false);
+      this.solutionsLengthScaleTabPage.ResumeLayout(false);
+      this.solutionsNetworkTabPage.ResumeLayout(false);
+      this.okbTabPage.ResumeLayout(false);
+      this.problemInstancesTabPage.ResumeLayout(false);
+      this.problemInstancesTabPage.PerformLayout();
+      this.problemInstancesTabControl.ResumeLayout(false);
+      this.instancesTabPage.ResumeLayout(false);
+      this.mapTabPage.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.instanceMapChart)).EndInit();
+      this.solutionsFdcTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label evaluationsLimitabel;
+    private System.Windows.Forms.TextBox maxEvaluationsTextBox;
+    private MainForm.WindowsForms.DragOverTabControl tabControl;
+    private System.Windows.Forms.TabPage runsTabPage;
+    private HeuristicLab.Optimization.Views.RunCollectionView runsView;
+    private System.Windows.Forms.OpenFileDialog openFileDialog;
+    private System.Windows.Forms.TabPage problemTabPage;
+    private MainForm.WindowsForms.ViewHost problemViewHost;
+    private System.Windows.Forms.TabPage algorithmTabPage;
+    private MainForm.WindowsForms.ViewHost algorithmViewHost;
+    private System.Windows.Forms.Label algorithmSuggestionLabel;
+    private System.Windows.Forms.ComboBox suggestedInstancesComboBox;
+    private System.Windows.Forms.TabPage okbTabPage;
+    private System.Windows.Forms.TabPage problemInstancesTabPage;
+    private System.Windows.Forms.Button refreshMapButton;
+    private System.Windows.Forms.Button okbDownloadButton;
+    private System.Windows.Forms.Panel progressPanel;
+    private MainForm.WindowsForms.ViewHost kbViewHost;
+    private System.Windows.Forms.Button algorithmStartButton;
+    private System.Windows.Forms.TabControl problemInstancesTabControl;
+    private System.Windows.Forms.TabPage instancesTabPage;
+    private MainForm.WindowsForms.ViewHost problemInstancesView;
+    private System.Windows.Forms.TabPage mapTabPage;
+    private Visualization.ChartControlsExtensions.EnhancedChart instanceMapChart;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ComboBox projectionComboBox;
+    private System.Windows.Forms.TabPage solutionsTabPage;
+    private System.Windows.Forms.TabControl solutionsTabControl;
+    private System.Windows.Forms.TabPage solutionsListTabPage;
+    private System.Windows.Forms.TabPage solutionsQualityTabPage;
+    private System.Windows.Forms.TabPage solutionsDiversityTabPage;
+    private System.Windows.Forms.Label qualityNameLabel;
+    private System.Windows.Forms.Label solutionNameLabel;
+    private System.Windows.Forms.ComboBox qualityNameComboBox;
+    private System.Windows.Forms.ComboBox solutionNameComboBox;
+    private MainForm.WindowsForms.ViewHost solutionsQualityViewHost;
+    private MainForm.WindowsForms.ViewHost solutionsViewHost;
+    private MainForm.WindowsForms.ViewHost solutionsDiversityViewHost;
+    private System.Windows.Forms.Label solutionDiversitySimilarityLabel;
+    private System.Windows.Forms.ComboBox similarityComboBox;
+    private System.Windows.Forms.TabPage solutionsLengthScaleTabPage;
+    private System.Windows.Forms.TabPage solutionsNetworkTabPage;
+    private MainForm.WindowsForms.ViewHost solutionsLengthScaleViewHost;
+    private MainForm.WindowsForms.ViewHost solutionsNetworkViewHost;
+    private System.Windows.Forms.TabPage solutionsFdcTabPage;
+    private MainForm.WindowsForms.ViewHost solutionsFdcViewHost;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.cs	(revision 13667)
@@ -0,0 +1,444 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Analysis;
+using HeuristicLab.Analysis.QualityAnalysis;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Views;
+using HeuristicLab.OptimizationExpertSystem.Common;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+
+namespace HeuristicLab.OptimizationExpertSystem {
+  [View("Expert-system Optimizer View")]
+  [Content(typeof(ExpertSystem), IsDefaultView = true)]
+  public partial class ExpertSystemView : NamedItemView {
+    protected TypeSelectorDialog problemTypeSelectorDialog;
+    protected virtual bool SuppressEvents { get; set; }
+    private bool okbDownloadInProgress;
+
+    public new ExpertSystem Content {
+      get { return (ExpertSystem)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ExpertSystemView() {
+      InitializeComponent();
+      // brings progress panel to front (it is not visible by default, but obstructs other elements in designer)
+      this.Controls.SetChildIndex(this.progressPanel, 0);
+      algorithmStartButton.Text = string.Empty;
+      algorithmStartButton.Image = VSImageLibrary.Play;
+      refreshMapButton.Text = string.Empty;
+      refreshMapButton.Image = VSImageLibrary.Refresh;
+    }
+
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (problemTypeSelectorDialog != null) problemTypeSelectorDialog.Dispose();
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.PropertyChanged -= ContentOnPropertyChanged;
+      Content.SuggestedInstances.CollectionReset -= SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsAdded -= SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsMoved -= SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsRemoved -= SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsReplaced -= SuggestedInstancesOnChanged;
+      Content.SolutionPool.ItemsAdded -= SolutionPoolOnChanged;
+      Content.SolutionPool.ItemsRemoved -= SolutionPoolOnChanged;
+      Content.SolutionPool.ItemsReplaced -= SolutionPoolOnChanged;
+      Content.SolutionPool.CollectionReset -= SolutionPoolOnChanged;
+      if (Content.Problem != null) Content.Problem.ProblemChanged -= ContentOnProblemChanged;
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.PropertyChanged += ContentOnPropertyChanged;
+      Content.SuggestedInstances.CollectionReset += SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsAdded += SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsMoved += SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsRemoved += SuggestedInstancesOnChanged;
+      Content.SuggestedInstances.ItemsReplaced += SuggestedInstancesOnChanged;
+      Content.SolutionPool.ItemsAdded += SolutionPoolOnChanged;
+      Content.SolutionPool.ItemsRemoved += SolutionPoolOnChanged;
+      Content.SolutionPool.ItemsReplaced += SolutionPoolOnChanged;
+      Content.SolutionPool.CollectionReset += SolutionPoolOnChanged;
+      if (Content.Problem != null) Content.Problem.ProblemChanged += ContentOnProblemChanged;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      SuppressEvents = true;
+      okbDownloadInProgress = false;
+      try {
+        if (Content == null) {
+          maxEvaluationsTextBox.Text = String.Empty;
+
+          problemViewHost.Content = null;
+          algorithmViewHost.Content = null;
+          runsView.Content = null;
+          solutionsViewHost.Content = null;
+          kbViewHost.Content = null;
+          problemInstancesView.Content = null;
+        } else {
+          maxEvaluationsTextBox.Text = Content.MaximumEvaluations.ToString();
+          problemViewHost.Content = Content.Problem;
+          runsView.Content = Content.Runs;
+          solutionsViewHost.Content = Content.SolutionPool;
+          kbViewHost.ViewType = typeof(RunCollectionRLDView);
+          kbViewHost.Content = Content.KnowledgeBase;
+          problemInstancesView.Content = Content.ProblemInstances;
+          algorithmViewHost.Content = Content.CurrentResult;
+        }
+      } finally { SuppressEvents = false; }
+      UpdateSuggestedInstancesCombobox();
+      UpdateNamesComboboxes();
+      UpdateSimilarityCalculators();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      maxEvaluationsTextBox.Enabled = Content != null && !ReadOnly && !Locked;
+      problemViewHost.Enabled = Content != null && !ReadOnly && !Locked && !okbDownloadInProgress;
+      suggestedInstancesComboBox.Enabled = Content != null && !ReadOnly && !Locked && !okbDownloadInProgress;
+      algorithmStartButton.Enabled = Content != null && !ReadOnly && !Locked && suggestedInstancesComboBox.SelectedIndex >= 0;
+      algorithmViewHost.Enabled = Content != null && !ReadOnly && !Locked;
+      runsView.Enabled = Content != null;
+      kbViewHost.Enabled = Content != null && !okbDownloadInProgress;
+      problemInstancesView.Enabled = Content != null && !okbDownloadInProgress;
+      refreshMapButton.Enabled = Content != null;
+      okbDownloadButton.Enabled = Content != null && Content.Problem != null && Content.Problem.ProblemId >= 0 && !ReadOnly && !Locked && !okbDownloadInProgress;
+    }
+
+    private void UpdateSuggestedInstancesCombobox() {
+      var prevSelection = (IAlgorithm)suggestedInstancesComboBox.SelectedItem;
+      var prevNewIndex = -1;
+      suggestedInstancesComboBox.Items.Clear();
+      if (Content == null) return;
+
+      for (var i = 0; i < Content.SuggestedInstances.Count; i++) {
+        suggestedInstancesComboBox.Items.Add(Content.SuggestedInstances[i]);
+        if (prevSelection == null || Content.SuggestedInstances[i].Name == prevSelection.Name)
+          prevNewIndex = prevSelection == null ? 0 : i;
+      }
+      if (prevNewIndex >= 0) {
+        suggestedInstancesComboBox.SelectedIndex = prevNewIndex;
+      }
+    }
+
+    private void UpdateNamesComboboxes() {
+      var selectedSolutionName = solutionNameComboBox.SelectedIndex >= 0 ? (string)solutionNameComboBox.SelectedItem : string.Empty;
+      var selectedQualityName = qualityNameComboBox.SelectedIndex >= 0 ? (string)qualityNameComboBox.SelectedItem : string.Empty;
+
+      solutionNameComboBox.Items.Clear();
+      qualityNameComboBox.Items.Clear();
+      if (Content == null) return;
+      var qualityNames = new HashSet<string>(Content.SolutionPool.SelectMany(x => x.Variables).Where(x => x.Value is DoubleValue).Select(x => x.Name));
+      var solutionNames = Content.SolutionPool.SelectMany(x => x.Variables).Where(x => !qualityNames.Contains(x.Name));
+
+      foreach (var sn in solutionNames.GroupBy(x => x.Name).OrderBy(x => x.Key)) {
+        solutionNameComboBox.Items.Add(sn.Key);
+        // either it was previously selected, or the variable value is defined in the HeuristicLab.Encodings sub-namespace
+        if (sn.Key == selectedSolutionName || (string.IsNullOrEmpty(selectedSolutionName) && sn.All(x => x.Value != null && x.Value.GetType().FullName.StartsWith("HeuristicLab.Encodings."))))
+          solutionNameComboBox.SelectedItem = sn.Key;
+      }
+      foreach (var qn in qualityNames.OrderBy(x => x)) {
+        qualityNameComboBox.Items.Add(qn);
+        if (qn == selectedQualityName || string.IsNullOrEmpty(selectedQualityName)) qualityNameComboBox.SelectedItem = qn;
+      }
+    }
+
+    private void UpdateSimilarityCalculators() {
+      var selected = (ISolutionSimilarityCalculator)(similarityComboBox.SelectedIndex >= 0 ? similarityComboBox.SelectedItem : null);
+      similarityComboBox.Items.Clear();
+      
+      if (Content == null || Content.Problem == null) return;
+
+      foreach (var calc in Content.Problem.Operators.OfType<ISolutionSimilarityCalculator>()) {
+        similarityComboBox.Items.Add(calc);
+        if (selected != null && calc.ItemName == selected.ItemName) similarityComboBox.SelectedItem = calc;
+      }
+      if (selected == null && similarityComboBox.Items.Count > 0)
+        similarityComboBox.SelectedIndex = 0;
+    }
+
+    #region Event Handlers
+    #region Content events
+    private void ContentOnProblemChanged(object sender, EventArgs eventArgs) {
+      UpdateSuggestedInstancesCombobox();
+      UpdateSimilarityCalculators();
+      SetEnabledStateOfControls();
+    }
+
+    private void ContentOnPropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, PropertyChangedEventArgs>)ContentOnPropertyChanged, sender, e);
+        return;
+      }
+      SuppressEvents = true;
+      try {
+        switch (e.PropertyName) {
+          case "KnowledgeBase": kbViewHost.Content = Content.KnowledgeBase; break;
+          case "MaximumEvaluations": maxEvaluationsTextBox.Text = Content.MaximumEvaluations.ToString(); break;
+          case "Problem":
+            problemViewHost.Content = Content.Problem;
+            Content.Problem.ProblemChanged += ContentOnProblemChanged;
+            break;
+          case "ProblemInstances": problemInstancesView.Content = Content.ProblemInstances; break;
+          case "CurrentResult": algorithmViewHost.Content = Content.CurrentResult; break;
+        }
+      } finally { SuppressEvents = false; }
+      SetEnabledStateOfControls();
+    }
+
+    private void SuggestedInstancesOnChanged(object sender, EventArgs e) {
+      UpdateSuggestedInstancesCombobox();
+    }
+
+    private void SolutionPoolOnChanged(object sender, EventArgs e) {
+      UpdateNamesComboboxes();
+      if (qualityNameComboBox.SelectedIndex >= 0) {
+        var qualityName = (string)qualityNameComboBox.SelectedItem;
+        UpdateSolutionQualityAnalysis(qualityName);
+      }
+      if (similarityComboBox.SelectedIndex >= 0) {
+        var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
+        UpdateSolutionDiversityAnalysis(calculator);
+        UpdateSolutionFdcAnalysis(calculator);
+        UpdateSolutionLengthScaleAnalysis(calculator);
+      } else solutionsDiversityViewHost.Content = null;
+    }
+    #endregion
+
+    #region Control events
+    private void MaxEvaluationsTextBoxOnValidating(object sender, CancelEventArgs e) {
+      if (SuppressEvents) return;
+      if (InvokeRequired) {
+        Invoke((Action<object, CancelEventArgs>)MaxEvaluationsTextBoxOnValidating, sender, e);
+        return;
+      }
+      int value;
+      if (!int.TryParse(maxEvaluationsTextBox.Text, out value)) {
+        e.Cancel = !maxEvaluationsTextBox.ReadOnly && maxEvaluationsTextBox.Enabled;
+        errorProvider.SetError(maxEvaluationsTextBox, "Please enter a valid integer number.");
+      } else {
+        Content.MaximumEvaluations = value;
+        e.Cancel = false;
+        errorProvider.SetError(maxEvaluationsTextBox, null);
+      }
+    }
+    #endregion
+    #endregion
+
+    private void RefreshMapButtonOnClick(object sender, EventArgs e) {
+      Content.UpdateInstanceProjection();
+      UpdateProjectionComboBox();
+    }
+
+    private void UpdateProjectionComboBox() {
+      projectionComboBox.Items.Clear();
+      var projStrings = Content.ProblemInstances
+        .SelectMany(x => x.Results.Where(y => Regex.IsMatch(y.Key, "^Projection[.].*[.][XY]$")))
+        .Select(x => Regex.Match(x.Key, "Projection[.](?<g>.*)[.][XY]").Groups["g"].Value)
+        .Distinct();
+      foreach (var str in projStrings) {
+        projectionComboBox.Items.Add(str);
+      }
+    }
+
+    private void OkbDownloadButtonOnClick(object sender, EventArgs e) {
+      if (Content.Problem.ProblemId == -1) {
+        MessageBox.Show("Please select a problem instance first.");
+        return;
+      }
+      var progress = new Progress();
+      progress.ProgressStateChanged += OkbDownloadProgressOnStateChanged;
+      Content.UpdateKnowledgeBaseAsync(progress);
+      MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().AddOperationProgressToView(progressPanel, progress);
+      progressPanel.Visible = true;
+      SetEnabledStateOfControls();
+    }
+
+    private void OkbDownloadProgressOnStateChanged(object sender, EventArgs eventArgs) {
+      var progress = (IProgress)sender;
+      okbDownloadInProgress = progress.ProgressState == ProgressState.Started;
+      SetEnabledStateOfControls();
+      if (!okbDownloadInProgress) {
+        progressPanel.Visible = false;
+        progress.ProgressStateChanged -= OkbDownloadProgressOnStateChanged;
+      }
+    }
+
+    private void AlgorithmStartButtonOnClick(object sender, EventArgs e) {
+      if (suggestedInstancesComboBox.SelectedIndex >= 0)
+        Content.StartAlgorithmAsync(suggestedInstancesComboBox.SelectedIndex);
+    }
+
+    private void ProjectionComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
+      if (projectionComboBox.SelectedIndex < 0) return;
+      var projection = (string)projectionComboBox.SelectedItem;
+      var instancesSeries = instanceMapChart.Series["InstancesSeries"];
+      var currentInstanceSeries = instanceMapChart.Series["CurrentInstanceSeries"];
+
+      instancesSeries.Points.Clear();
+      currentInstanceSeries.Points.Clear();
+
+      foreach (var run in Content.ProblemInstances) {
+        var xKey = "Projection." + projection + ".X";
+        var yKey = "Projection." + projection + ".Y";
+        if (!run.Results.ContainsKey(xKey) || !run.Results.ContainsKey(yKey)
+          || !(run.Results[xKey] is Data.DoubleValue) || !(run.Results[yKey] is Data.DoubleValue)) continue;
+        var x = ((Data.DoubleValue)run.Results[xKey]).Value;
+        var y = ((Data.DoubleValue)run.Results[yKey]).Value;
+        var dataPoint = new DataPoint(x, y) {
+          Label = run.Name
+        };
+        instancesSeries.Points.Add(dataPoint);
+      }
+
+      var curPoint = Content.ProjectCurrentInstance(projection);
+      if (curPoint != null) {
+        var dp = new DataPoint(curPoint.Item1, curPoint.Item2) {
+          Label = Content.Problem.Problem.Name
+        };
+        currentInstanceSeries.Points.Add(dp);
+      }
+    }
+
+    private void UpdateSolutionQualityAnalysis(string qualityName) {
+      var dt = solutionsQualityViewHost.Content as DataTable;
+      if (dt == null) {
+        dt = QualityDistributionAnalyzer.PrepareTable(qualityName);
+        solutionsQualityViewHost.Content = dt;
+      }
+      QualityDistributionAnalyzer.UpdateTable(dt, Content.SolutionPool.Where(x => x.Variables.ContainsKey(qualityName)).Select(x => x.Variables[qualityName].Value).OfType<DoubleValue>().Select(x => x.Value));
+    }
+
+    private void UpdateSolutionDiversityAnalysis(ISolutionSimilarityCalculator calculator) {
+      try {
+        solutionsDiversityViewHost.Content = null;
+        if (Content.SolutionPool == null) return;
+        var similarities = new double[Content.SolutionPool.Count, Content.SolutionPool.Count];
+        for (int i = 0; i < Content.SolutionPool.Count; i++) {
+          for (int j = 0; j < Content.SolutionPool.Count; j++)
+            similarities[i, j] = calculator.CalculateSolutionSimilarity(Content.SolutionPool[i], Content.SolutionPool[j]);
+        }
+        var hm = new HeatMap(similarities, "Solution Similarities", 0.0, 1.0);
+        solutionsDiversityViewHost.Content = hm;
+      } catch { }
+    }
+
+    private void UpdateSolutionFdcAnalysis(ISolutionSimilarityCalculator calculator) {
+      try {
+        solutionsFdcViewHost.Content = null;
+        if (Content.SolutionPool == null) return;
+        var points = new List<Point2D<double>>();
+        for (int i = 0; i < Content.SolutionPool.Count; i++) {
+          for (int j = 0; j < Content.SolutionPool.Count; j++) {
+            if (i == j) continue;
+            var qDiff = Math.Abs(((DoubleValue)Content.SolutionPool[i].Variables[calculator.QualityVariableName].Value).Value - ((DoubleValue)Content.SolutionPool[j].Variables[calculator.QualityVariableName].Value).Value);
+            points.Add(new Point2D<double>(qDiff, 1.0 - calculator.CalculateSolutionSimilarity(Content.SolutionPool[i], Content.SolutionPool[j])));
+          }
+        }
+        var splot = new ScatterPlot("Fitness-Distance", "");
+        var row = new ScatterPlotDataRow("Fdc", "", points);
+        row.VisualProperties.PointSize = 7;
+        splot.Rows.Add(row);
+        solutionsFdcViewHost.Content = splot;
+      } catch { }
+    }
+
+    private void UpdateSolutionLengthScaleAnalysis(ISolutionSimilarityCalculator calculator) {
+      try {
+        solutionsLengthScaleViewHost.Content = null;
+        if (Content.SolutionPool == null) return;
+        var dt = solutionsLengthScaleViewHost.Content as DataTable;
+        if (dt == null) {
+          dt = QualityDistributionAnalyzer.PrepareTable("Length Scale");
+          solutionsLengthScaleViewHost.Content = dt;
+        }
+
+        QualityDistributionAnalyzer.UpdateTable(dt, CalculateLengthScale(calculator));
+      } catch { }
+    }
+
+    private IEnumerable<double> CalculateLengthScale(ISolutionSimilarityCalculator calculator) {
+      for (int i = 0; i < Content.SolutionPool.Count; i++) {
+        for (int j = 0; j < Content.SolutionPool.Count; j++) {
+          if (i == j) continue;
+          var sim = calculator.CalculateSolutionSimilarity(Content.SolutionPool[i], Content.SolutionPool[j]);
+          if (sim.IsAlmost(0)) continue;
+          var qDiff = Math.Abs(((DoubleValue)Content.SolutionPool[i].Variables[calculator.QualityVariableName].Value).Value - ((DoubleValue)Content.SolutionPool[j].Variables[calculator.QualityVariableName].Value).Value);
+          yield return qDiff / sim;
+        }
+      }
+    }
+
+    private void SuggestedInstancesComboBoxOnSelectedIndexChanged(object sender, EventArgs e) {
+      SetEnabledStateOfControls();
+    }
+
+    private void qualityNameComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (qualityNameComboBox.SelectedIndex < 0) return;
+      solutionsQualityViewHost.Content = null;
+      solutionsDiversityViewHost.Content = null;
+      var qualityName = (string)qualityNameComboBox.SelectedItem;
+      UpdateSolutionQualityAnalysis(qualityName);
+      var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
+      if (calculator != null) calculator.QualityVariableName = qualityName;
+      UpdateSolutionDiversityAnalysis(calculator);
+      UpdateSolutionFdcAnalysis(calculator);
+      UpdateSolutionLengthScaleAnalysis(calculator);
+    }
+
+    private void solutionNameComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
+      if (calculator != null) calculator.SolutionVariableName = (string)solutionNameComboBox.SelectedItem;
+      UpdateSolutionDiversityAnalysis(calculator);
+      UpdateSolutionFdcAnalysis(calculator);
+      UpdateSolutionLengthScaleAnalysis(calculator);
+    }
+
+    private void similarityComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      var calculator = (ISolutionSimilarityCalculator)similarityComboBox.SelectedItem;
+      if (calculator != null) {
+        calculator.SolutionVariableName = (string)solutionNameComboBox.SelectedItem;
+        calculator.QualityVariableName = (string)qualityNameComboBox.SelectedItem;
+      }
+      UpdateSolutionDiversityAnalysis(calculator);
+      UpdateSolutionFdcAnalysis(calculator);
+      UpdateSolutionLengthScaleAnalysis(calculator);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.resx
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.resx	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ExpertSystemView.resx	(revision 13667)
@@ -0,0 +1,129 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>140, 17</value>
+  </metadata>
+  <metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>230, 17</value>
+  </metadata>
+</root>
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj	(revision 13667)
@@ -0,0 +1,240 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{6240A044-BD4B-4DDB-9E67-A6CFA5E0C7BE}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.OptimizationExpertSystem</RootNamespace>
+    <AssemblyName>HeuristicLab.OptimizationExpertSystem-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.7.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Clients.Access-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Clients.Access-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Clients.OKB-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Clients.OKB-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ExpertSystemView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ExpertSystemView.Designer.cs">
+      <DependentUpon>ExpertSystemView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Interfaces\IOptimizationExpertSystemUi.cs" />
+    <Compile Include="OptimizationExpertSystem.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="OptimizationExpertSystem.Designer.cs">
+      <DependentUpon>OptimizationExpertSystem.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Plugin.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis.Views\3.3\HeuristicLab.Analysis.Views-3.3.csproj">
+      <Project>{76945d76-ca61-4147-9dc2-0acdcddf87f9}</Project>
+      <Name>HeuristicLab.Analysis.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj">
+      <Project>{662b4b15-8f4d-4ae5-b3eb-d91c215f5af2}</Project>
+      <Name>HeuristicLab.Optimization.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.OptimizationExpertSystem.Common\3.3\HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj">
+      <Project>{492cc257-e27c-4497-b2c1-09c45310c91c}</Project>
+      <Name>HeuristicLab.OptimizationExpertSystem.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="ExpertSystemView.resx">
+      <DependentUpon>ExpertSystemView.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="OptimizationExpertSystem.resx">
+      <DependentUpon>OptimizationExpertSystem.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj.DotSettings
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj.DotSettings	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj.DotSettings	(revision 13667)
@@ -0,0 +1,2 @@
+﻿<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interfaces/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj.user
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj.user	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem-3.3.csproj.user	(revision 13667)
@@ -0,0 +1,8 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
+    <StartAction>Program</StartAction>
+    <StartProgram>C:\Users\P40311\Work\HL3\trunk\sources\bin\HeuristicLab 3.3.exe</StartProgram>
+    <StartArguments>/start:"Optimization Expert System" /hideStarter</StartArguments>
+  </PropertyGroup>
+</Project>
Index: anches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj	(revision 13666)
+++ 	(revision )
@@ -1,180 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{492CC257-E27C-4497-B2C1-09C45310C91C}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>HeuristicLab.OptimizationExpertSystem.Common</RootNamespace>
-    <AssemblyName>HeuristicLab.OptimizationExpertSystem.Common-3.3</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SignAssembly>true</SignAssembly>
-  </PropertyGroup>
-  <PropertyGroup>
-    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x86</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x86</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.7.0.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Clients.OKB-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Clients.OKB-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Collections-3.3">
-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Common-3.3">
-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Core-3.3">
-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3">
-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.MainForm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Persistence-3.3">
-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.QuadraticAssignment-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.QuadraticAssignment-3.3.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="ExpertSystem.cs" />
-    <Compile Include="Plugin.cs" />
-    <None Include="Properties\AssemblyInfo.cs.frame" />
-    <Compile Include="ProblemCharacteristicAnalysis\CharacteristicCalculator.cs" />
-    <Compile Include="ProblemCharacteristicAnalysis\DoubleMatrixCharacteristicCalculator.cs" />
-    <Compile Include="ProblemCharacteristicAnalysis\QAP\QAPCharacteristicCalculator.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="HeuristicLab.snk" />
-    <None Include="Plugin.cs.frame" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
-      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
-      <Name>HeuristicLab.Analysis-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
-      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
-      <Name>HeuristicLab.Optimization-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
-set ProjectDir=$(ProjectDir)
-set SolutionDir=$(SolutionDir)
-set Outdir=$(Outdir)
-
-call PreBuildEvent.cmd</PreBuildEvent>
-  </PropertyGroup>
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Interfaces/IOptimizationExpertSystemUi.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Interfaces/IOptimizationExpertSystemUi.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Interfaces/IOptimizationExpertSystemUi.cs	(revision 13667)
@@ -0,0 +1,24 @@
+﻿#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
+
+namespace HeuristicLab.OptimizationExpertSystem {
+  public interface IOptimizationExpertSystemUi { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.Designer.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.Designer.cs	(revision 13667)
@@ -0,0 +1,44 @@
+﻿namespace HeuristicLab.OptimizationExpertSystem {
+  partial class OptimizationExpertSystem {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.SuspendLayout();
+      // 
+      // OptimizationExpertSystem
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(624, 412);
+      this.Name = "OptimizationExpertSystem";
+      this.Text = "Optimization Expert System (OES)";
+      this.Title = "Optimization Expert System (OES)";
+      this.Load += new System.EventHandler(this.OptimizationExpertSystem_Load);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.cs	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.cs	(revision 13667)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.OptimizationExpertSystem.Common;
+using System;
+
+namespace HeuristicLab.OptimizationExpertSystem {
+  public partial class OptimizationExpertSystem : DockingMainForm {
+
+    public ExpertSystem ExpertSystem { get; private set; }
+
+    public OptimizationExpertSystem(Type userInterfaceType) : base(userInterfaceType) {
+      InitializeComponent();
+      ExpertSystem = new ExpertSystem();
+    }
+
+    private void OptimizationExpertSystem_Load(object sender, EventArgs e) {
+      ShowContent(ExpertSystem);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.resx
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.resx	(revision 13667)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/OptimizationExpertSystem.resx	(revision 13667)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Plugin.cs.frame	(revision 13666)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Plugin.cs.frame	(revision 13667)
@@ -20,12 +20,14 @@
 #endregion
 
+using System.Windows.Forms;
+using HeuristicLab.Clients.Access;
 using HeuristicLab.PluginInfrastructure;
 
-namespace HeuristicLab.OptimizationExpertSystem.Common {
+namespace HeuristicLab.OptimizationExpertSystem {
   /// <summary>
   /// Plugin class for HeuristicLab.OptimizationExpertSystem plugin.
   /// </summary>
-  [Plugin("HeuristicLab.OptimizationExpertSystem.Common", "3.3.12.$WCREV$")]
-  [PluginFile("HeuristicLab.OptimizationExpertSystem.Common-3.3.dll", PluginFileType.Assembly)]
+  [Plugin("HeuristicLab.OptimizationExpertSystem", "3.3.12.$WCREV$")]
+  [PluginFile("HeuristicLab.OptimizationExpertSystem-3.3.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
@@ -36,6 +38,20 @@
   [PluginDependency("HeuristicLab.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.OptimizationExpertSystem.Common", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
   public class HeuristicLabOptimizationExpertSystemPlugin : PluginBase {
   }
+
+  [Application("Optimization Expert System", "HeuristicLab Optimization Expert System 3.3.13.$WCREV$")]
+  internal class HeuristicLabOptimizationExpertSystemApplication : ApplicationBase {
+    public override void Run(ICommandLineArgument[] args) {
+      HeuristicLab.MainForm.WindowsForms.MainForm mainForm = new OptimizationExpertSystem(typeof(IOptimizationExpertSystemUi));
+      
+      ClientInformation.InitializeAsync();
+      UserInformation.InitializeAsync();
+
+      mainForm.ShowContentInViewHost = true;
+      Application.Run(mainForm);
+    }
+  }
 }
Index: /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Properties/AssemblyInfo.cs.frame	(revision 13666)
+++ /branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/Properties/AssemblyInfo.cs.frame	(revision 13667)
@@ -11,5 +11,5 @@
 [assembly: AssemblyCompany("HEAL")]
 [assembly: AssemblyProduct("HeuristicLab")]
-[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyCopyright("(c) 2002-2016 HEAL")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -21,5 +21,5 @@
 
 // The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("9b7ac6bf-de48-4049-a031-26c97e91dc3e")]
+[assembly: Guid("251351ad-a274-436f-a024-7706355369cb")]
 
 // Version information for an assembly consists of the following four values:
Index: /branches/PerformanceComparison/PerformanceComparison.sln
===================================================================
--- /branches/PerformanceComparison/PerformanceComparison.sln	(revision 13666)
+++ /branches/PerformanceComparison/PerformanceComparison.sln	(revision 13667)
@@ -12,7 +12,7 @@
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Optimization.Views-3.3", "HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj", "{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.OptimizationExpertSystem-3.3", "HeuristicLab.OptimizationExpertSystem\3.3\HeuristicLab.OptimizationExpertSystem-3.3.csproj", "{492CC257-E27C-4497-B2C1-09C45310C91C}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.OptimizationExpertSystem-3.3", "HeuristicLab.OptimizationExpertSystem.Common\3.3\HeuristicLab.OptimizationExpertSystem.Common-3.3.csproj", "{492CC257-E27C-4497-B2C1-09C45310C91C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.OptimizationExpertSystem.Views-3.3", "HeuristicLab.OptimizationExpertSystem.Views\3.3\HeuristicLab.OptimizationExpertSystem.Views-3.3.csproj", "{6240A044-BD4B-4DDB-9E67-A6CFA5E0C7BE}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.OptimizationExpertSystem.Views-3.3", "HeuristicLab.OptimizationExpertSystem.\3.3\HeuristicLab.OptimizationExpertSystem-3.3.csproj", "{6240A044-BD4B-4DDB-9E67-A6CFA5E0C7BE}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Analysis.FitnessLandscape-3.3", "HeuristicLab.Analysis.FitnessLandscape\3.3\HeuristicLab.Analysis.FitnessLandscape-3.3.csproj", "{5FBDCD4A-3C2A-4EC6-83CE-34B29F43621A}"
