Index: /stable/HeuristicLab 3.3.sln
===================================================================
--- /stable/HeuristicLab 3.3.sln	(revision 15243)
+++ /stable/HeuristicLab 3.3.sln	(revision 15244)
@@ -2,5 +2,5 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 15
-VisualStudioVersion = 15.0.26430.6
+VisualStudioVersion = 15.0.26430.15
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96396439-A764-4022-A8D2-BE021449B8D1}"
@@ -455,4 +455,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.GraphColoring-3.3", "HeuristicLab.Problems.GraphColoring\3.3\HeuristicLab.Problems.GraphColoring-3.3.csproj", "{4B76E2CB-A990-4959-B080-1D81D418D325}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3", "HeuristicLab.Algorithms.MOCMAEvolutionStrategy\3.3\HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj", "{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}"
 EndProject
 Global
@@ -2218,4 +2220,16 @@
 		{4B76E2CB-A990-4959-B080-1D81D418D325}.Release|x86.ActiveCfg = Release|x86
 		{4B76E2CB-A990-4959-B080-1D81D418D325}.Release|x86.Build.0 = Release|x86
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x64.ActiveCfg = Debug|x64
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x64.Build.0 = Debug|x64
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x86.ActiveCfg = Debug|x86
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Debug|x86.Build.0 = Debug|x86
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x64.ActiveCfg = Release|x64
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x64.Build.0 = Release|x64
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x86.ActiveCfg = Release|x86
+		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/DoubleMatrixHelper.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/DoubleMatrixHelper.cs	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/DoubleMatrixHelper.cs	(revision 15244)
@@ -0,0 +1,50 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ * 
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  internal static class DoubleMatrixHelper {
+    internal static double[][] ToJaggedArray(this DoubleMatrix m) {
+      if (m == null) return null;
+      var i = m.Rows - 1;
+      var a = new double[i][];
+      for (i--; i >= 0; i--) {
+        var j = m.Columns;
+        a[i] = new double[j];
+        for (j--; j >= 0; j--) a[i][j] = m[i, j];
+      }
+      return a;
+    }
+
+    internal static DoubleMatrix ToMatrix(this IEnumerable<IReadOnlyList<double>> data) {
+      var d2 = data.ToArray();
+      var mat = new DoubleMatrix(d2.Length, d2[0].Count);
+      for (var i = 0; i < mat.Rows; i++)
+        for (var j = 0; j < mat.Columns; j++)
+          mat[i, j] = d2[i][j];
+      return mat;
+    }
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj	(revision 15244)
@@ -0,0 +1,193 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.MOCMAEvolutionStrategy</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.MOCMAEvolutionStrategy-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>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <LangVersion>5</LangVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <LangVersion>5</LangVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <LangVersion>5</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <LangVersion>5</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>5</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <LangVersion>5</LangVersion>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.7.0">
+      <HintPath>..\..\bin\ALGLIB-3.7.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Indicators\MinimalDistanceIndicator.cs" />
+    <Compile Include="Indicators\CrowdingIndicator.cs" />
+    <Compile Include="Indicators\HypervolumeIndicator.cs" />
+    <Compile Include="IIndicator.cs" />
+    <Compile Include="Individual.cs" />
+    <Compile Include="MOCMAEvolutionStrategy.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="DoubleMatrixHelper.cs" />
+  </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.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.RealVectorEncoding\3.3\HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj">
+      <Project>{BB6D334A-4BB6-4674-9883-31A6EBB32CAB}</Project>
+      <Name>HeuristicLab.Encodings.RealVectorEncoding-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
+      <Project>{23da7ff4-d5b8-41b6-aa96-f0561d24f3ee}</Project>
+      <Name>HeuristicLab.Operators-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>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
+      <Project>{102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}</Project>
+      <Name>HeuristicLab.Persistence-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186a6a-5176-4402-ae83-886557b53cca}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj">
+      <Project>{3540e29e-4793-49e7-8ee2-fea7f61c3994}</Project>
+      <Name>HeuristicLab.Problems.Instances-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.TestFunctions.MultiObjective\3.3\HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj">
+      <Project>{D53E8E48-CFAA-4F57-AC35-63BEF4476159}</Project>
+      <Name>HeuristicLab.Problems.TestFunctions.MultiObjective-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
+      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
+      <Name>HeuristicLab.Random-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+    </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+    </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: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs	(revision 15244)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  public interface IIndicator : IItem {
+    /// <summary>
+    ///  Selects the least contributing Point of a front. Please keep in mind, that the contribution of a point depends on its value as well as on the other points of a front. 
+    ///  A particularly good point may not be as benefical in another front.
+    /// </summary>
+    /// <typeparam name="TR"></typeparam>
+    /// <param name="front">a front which will be evaluated</param>
+    /// <param name="problem">The problem on which the front is evaluated (!! The function itself will NOT be evluated only bounds referencePoints & other metadata will be used</param>
+    /// <returns>the index of the least contributing point according to any type of quality criteria</returns>
+    int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem);
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 15244)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  [Item("CrowdingIndicator", "Selection of Offspring based on CrowdingDistance")]
+  [StorableClass]
+  internal class CrowdingIndicator : Item, IIndicator {
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected CrowdingIndicator(bool deserializing) : base(deserializing) { }
+    protected CrowdingIndicator(CrowdingIndicator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new CrowdingIndicator(this, cloner); }
+    public CrowdingIndicator() { }
+    #endregion
+
+    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem) {
+      var bounds = problem.Encoding.Bounds;
+      var extracted = front.Select(x => x.PenalizedFitness).ToArray();
+      if (extracted.Length <= 2) return 0;
+      var pointsums = new double[extracted.Length];
+
+      for (var dim = 0; dim < problem.Maximization.Length; dim++) {
+        var arr = extracted.Select(x => x[dim]).ToArray();
+        Array.Sort(arr);
+        var fmax = problem.Encoding.Bounds[dim % bounds.Rows, 1];
+        var fmin = bounds[dim % bounds.Rows, 0];
+        var pointIdx = 0;
+        foreach (var point in extracted) {
+          var pos = Array.BinarySearch(arr, point[dim]);
+          var d = pos != 0 && pos != arr.Length - 1 ? (arr[pos + 1] - arr[pos - 1]) / (fmax - fmin) : double.PositiveInfinity;
+          pointsums[pointIdx] += d;
+          pointIdx++;
+        }
+      }
+      return pointsums.Select((value, index) => new { value, index }).OrderBy(x => x.value).First().index;
+    }
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 15244)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  [Item("HypervolumeIndicator", "Selection of Offspring based on contributing Hypervolume")]
+  [StorableClass]
+  internal class HypervolumeIndicator : Item, IIndicator {
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected HypervolumeIndicator(bool deserializing) : base(deserializing) { }
+    protected HypervolumeIndicator(HypervolumeIndicator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new HypervolumeIndicator(this, cloner); }
+    public HypervolumeIndicator() { }
+    #endregion
+
+    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem) {
+      var frontCopy = front.Select(x => x.PenalizedFitness).ToList();
+      if (frontCopy.Count <= 1) return 0;
+      var p = problem as MultiObjectiveTestFunctionProblem;
+      var refPoint = BuildReferencePoint(p != null ? frontCopy.Concat(new[] { p.ReferencePoint.CloneAsArray() }) : frontCopy, problem.Maximization);
+      var contributions = Enumerable.Range(0, frontCopy.Count).Select(i => Contribution(frontCopy, i, problem.Maximization, refPoint));
+      return contributions.Select((value, index) => new { value, index }).OrderBy(x => x.value).First().index;
+    }
+
+    #region Helpers
+    private static double Contribution(IList<double[]> front, int idx, bool[] maximization, double[] refPoint) {
+      var point = front[idx];
+      front.RemoveAt(idx);
+      var contribution = -Hypervolume.Calculate(front.ToArray(), refPoint, maximization);
+      front.Insert(idx, point);
+      return contribution;
+    }
+    private static double[] BuildReferencePoint(IEnumerable<double[]> front, IReadOnlyList<bool> maximization) {
+      var refPoint = new double[maximization.Count];
+      foreach (var point in front)
+        for (var i = 0; i < maximization.Count; i++)
+          refPoint[i] = maximization[i] ? Math.Min(refPoint[i], point[i]) : Math.Max(refPoint[i], point[i]);
+      return refPoint;
+    }
+    #endregion
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 15244)
@@ -0,0 +1,100 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  [Item("MinimalDistanceIndicator", "Selection of Offspring based on distance to nearest neighbour")]
+  [StorableClass]
+  internal class MinimalDistanceIndicator : Item, IIndicator {
+
+    #region Constructor and Cloning
+    [StorableConstructor]
+    protected MinimalDistanceIndicator(bool deserializing) : base(deserializing) { }
+    protected MinimalDistanceIndicator(MinimalDistanceIndicator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new MinimalDistanceIndicator(this, cloner); }
+    public MinimalDistanceIndicator() { }
+    #endregion
+
+    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem) {
+      var extracted = front.Select(x => x.PenalizedFitness).ToArray();
+      if (extracted.Length <= 2) return 0;
+      var distances = CalcDistances(extracted);
+      var mindexI = 0;
+      var mindexJ = 0;
+      var min = double.MaxValue;
+      for (var i = 0; i < extracted.Length; i++) {
+        var d = double.MaxValue;
+        var minj = 0;
+        for (var j = 0; j < extracted.Length; j++) {
+          if (i == j) continue;
+          var d1 = distances[i, j];
+          if (!(d1 < d)) continue;
+          minj = j;
+          d = d1;
+        }
+        if (!(d < min)) continue;
+        min = d;
+        mindexI = i;
+        mindexJ = minj;
+      }
+
+      //break tie with distance to second nearest
+      var minI = double.MaxValue;
+      var minJ = double.MaxValue;
+
+      for (var i = 0; i < extracted.Length; i++) {
+        double d;
+        if (mindexI != i) {
+          d = distances[mindexI, i];
+          if (!d.IsAlmost(min)) minI = Math.Min(minI, d);
+        }
+        if (mindexJ == i) continue;
+        d = distances[mindexJ, i];
+        if (!d.IsAlmost(min)) minJ = Math.Min(minJ, d);
+      }
+
+      //find min
+      return minI < minJ ? mindexI : mindexJ;
+    }
+
+    #region Helpers
+    private static double[,] CalcDistances(IReadOnlyList<double[]> extracted) {
+      var res = new double[extracted.Count, extracted.Count];
+      for (var i = 0; i < extracted.Count; i++)
+        for (var j = 0; j < i; j++)
+          res[i, j] = res[j, i] = Dist(extracted[i], extracted[j]);
+      return res;
+    }
+
+    private static double Dist(IEnumerable<double> a, IEnumerable<double> b) {
+      return Math.Sqrt(a.Zip(b, (x, y) => (x - y) * (x - y)).Sum());
+    }
+    #endregion
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Individual.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Individual.cs	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Individual.cs	(revision 15244)
@@ -0,0 +1,197 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ * 
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  [StorableClass]
+  public class Individual : IDeepCloneable {
+
+    #region Properties
+    [Storable]
+    private MOCMAEvolutionStrategy strategy;
+
+    //Chromosome
+    [Storable]
+    public RealVector Mean { get; private set; }
+    [Storable]
+    private double sigma;//stepsize
+    [Storable]
+    private RealVector evolutionPath; // pc
+    [Storable]
+    private RealVector lastStep;
+    [Storable]
+    private RealVector lastZ;
+    [Storable]
+    private double[,] lowerCholesky;
+
+    //Phenotype
+    [Storable]
+    public double[] Fitness { get; set; }
+    [Storable]
+    public double[] PenalizedFitness { get; set; }
+    [Storable]
+    public bool Selected { get; set; }
+    [Storable]
+    public double SuccessProbability { get; set; }
+    #endregion
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected Individual(bool deserializing) { }
+
+    public Individual(RealVector mean, double pSucc, double sigma, RealVector pc, double[,] c, MOCMAEvolutionStrategy strategy) {
+      Mean = mean;
+      lastStep = new RealVector(mean.Length);
+      SuccessProbability = pSucc;
+      this.sigma = sigma;
+      evolutionPath = pc;
+      CholeskyDecomposition(c);
+      Selected = true;
+      this.strategy = strategy;
+    }
+
+    public Individual(Individual other) {
+      SuccessProbability = other.SuccessProbability;
+      sigma = other.sigma;
+      evolutionPath = (RealVector)other.evolutionPath.Clone();
+      Mean = (RealVector)other.Mean.Clone();
+      lowerCholesky = (double[,])other.lowerCholesky.Clone();
+      Selected = true;
+      strategy = other.strategy;
+    }
+
+    public Individual(Individual other, Cloner cloner) {
+      strategy = cloner.Clone(other.strategy);
+      Mean = cloner.Clone(other.Mean);
+      sigma = other.sigma;
+      evolutionPath = cloner.Clone(other.evolutionPath);
+      lastStep = cloner.Clone(other.evolutionPath);
+      lastZ = cloner.Clone(other.lastZ);
+      lowerCholesky = other.lowerCholesky != null ? other.lowerCholesky.Clone() as double[,] : null;
+      Fitness = other.Fitness != null ? other.Fitness.Select(x => x).ToArray() : null;
+      PenalizedFitness = other.PenalizedFitness != null ? other.PenalizedFitness.Select(x => x).ToArray() : null;
+      Selected = other.Selected;
+      SuccessProbability = other.SuccessProbability;
+    }
+
+    public object Clone() {
+      return new Cloner().Clone(this);
+    }
+
+    public IDeepCloneable Clone(Cloner cloner) {
+      return new Individual(this, cloner);
+    }
+    #endregion
+
+    public void Mutate(NormalDistributedRandom gauss) {
+      //sampling a random z from N(0,I) where I is the Identity matrix;
+      lastZ = new RealVector(Mean.Length);
+      var n = lastZ.Length;
+      for (var i = 0; i < n; i++) lastZ[i] = gauss.NextDouble();
+      //Matrixmultiplication: lastStep = lowerCholesky * lastZ;
+      lastStep = new RealVector(Mean.Length);
+      for (var i = 0; i < n; i++) {
+        double sum = 0;
+        for (var j = 0; j <= i; j++) sum += lowerCholesky[i, j] * lastZ[j];
+        lastStep[i] = sum;
+      }
+      //add the step to x weighted by stepsize;
+      for (var i = 0; i < Mean.Length; i++) Mean[i] += sigma * lastStep[i];
+    }
+
+    public void UpdateAsParent(bool offspringSuccessful) {
+      SuccessProbability = (1 - strategy.StepSizeLearningRate) * SuccessProbability + strategy.StepSizeLearningRate * (offspringSuccessful ? 1 : 0);
+      sigma *= Math.Exp(1 / strategy.StepSizeDampeningFactor * (SuccessProbability - strategy.TargetSuccessProbability) / (1 - strategy.TargetSuccessProbability));
+      if (!offspringSuccessful) return;
+      if (SuccessProbability < strategy.SuccessThreshold && lastZ != null) {
+        var stepNormSqr = lastZ.Sum(d => d * d);
+        var rate = strategy.CovarianceMatrixUnlearningRate;
+        if (stepNormSqr > 1 && 1 < strategy.CovarianceMatrixUnlearningRate * (2 * stepNormSqr - 1)) rate = 1 / (2 * stepNormSqr - 1);
+        CholeskyUpdate(lastStep, 1 + rate, -rate);
+      } else RoundUpdate();
+    }
+
+    public void UpdateAsOffspring() {
+      SuccessProbability = (1 - strategy.StepSizeLearningRate) * SuccessProbability + strategy.StepSizeLearningRate;
+      sigma *= Math.Exp(1 / strategy.StepSizeDampeningFactor * (SuccessProbability - strategy.TargetSuccessProbability) / (1 - strategy.TargetSuccessProbability));
+      var evolutionpathUpdateWeight = strategy.EvolutionPathLearningRate * (2.0 - strategy.EvolutionPathLearningRate);
+      if (SuccessProbability < strategy.SuccessThreshold) {
+        UpdateEvolutionPath(1 - strategy.EvolutionPathLearningRate, evolutionpathUpdateWeight);
+        CholeskyUpdate(evolutionPath, 1 - strategy.CovarianceMatrixLearningRate, strategy.CovarianceMatrixLearningRate);
+      } else RoundUpdate();
+    }
+
+    public void UpdateEvolutionPath(double learningRate, double updateWeight) {
+      updateWeight = Math.Sqrt(updateWeight);
+      for (var i = 0; i < evolutionPath.Length; i++) {
+        evolutionPath[i] *= learningRate;
+        evolutionPath[i] += updateWeight * lastStep[i];
+      }
+    }
+
+    #region Helpers
+    private void CholeskyDecomposition(double[,] c) {
+      if (!alglib.spdmatrixcholesky(ref c, c.GetLength(0), false))
+        throw new ArgumentException("Covariancematrix is not symmetric positiv definit");
+      lowerCholesky = (double[,])c.Clone();
+    }
+
+    private void CholeskyUpdate(RealVector v, double alpha, double beta) {
+      var n = v.Length;
+      var temp = new double[n];
+      for (var i = 0; i < n; i++) temp[i] = v[i];
+      double betaPrime = 1;
+      var a = Math.Sqrt(alpha);
+      for (var j = 0; j < n; j++) {
+        var ljj = a * lowerCholesky[j, j];
+        var dj = ljj * ljj;
+        var wj = temp[j];
+        var swj2 = beta * wj * wj;
+        var gamma = dj * betaPrime + swj2;
+        var x1 = dj + swj2 / betaPrime;
+        if (x1 < 0.0) return;
+        var nLjj = Math.Sqrt(x1);
+        lowerCholesky[j, j] = nLjj;
+        betaPrime += swj2 / dj;
+        if (j + 1 >= n) continue;
+        for (var i = j + 1; i < n; i++) lowerCholesky[i, j] *= a;
+        for (var i = j + 1; i < n; i++) temp[i] = wj / ljj * lowerCholesky[i, j];
+        if (gamma.IsAlmost(0)) continue;
+        for (var i = j + 1; i < n; i++) lowerCholesky[i, j] *= nLjj / ljj;
+        for (var i = j + 1; i < n; i++) lowerCholesky[i, j] += nLjj * beta * wj / gamma * temp[i];
+      }
+    }
+
+    private void RoundUpdate() {
+      var evolutionPathUpdateWeight = strategy.EvolutionPathLearningRate * (2.0 - strategy.EvolutionPathLearningRate);
+      UpdateEvolutionPath(1 - strategy.EvolutionPathLearningRate, 0);
+      CholeskyUpdate(evolutionPath, 1 - strategy.CovarianceMatrixLearningRate + evolutionPathUpdateWeight, strategy.CovarianceMatrixLearningRate);
+    }
+    #endregion
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 15244)
@@ -0,0 +1,504 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ * 
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  [Item("Multi-Objective CMA Evolution Strategy (MOCMAES)", "A multi objective evolution strategy based on covariance matrix adaptation. Code is based on 'Covariance Matrix Adaptation for Multi - objective Optimization' by Igel, Hansen and Roth")]
+  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 210)]
+  [StorableClass]
+  public class MOCMAEvolutionStrategy : BasicAlgorithm {
+    public override Type ProblemType {
+      get { return typeof(MultiObjectiveBasicProblem<RealVectorEncoding>); }
+    }
+    public new MultiObjectiveBasicProblem<RealVectorEncoding> Problem {
+      get { return (MultiObjectiveBasicProblem<RealVectorEncoding>)base.Problem; }
+      set { base.Problem = value; }
+    }
+    public override bool SupportsPause {
+      get { return true; }
+    }
+
+    #region Storable fields
+    [Storable]
+    private IRandom random = new MersenneTwister();
+    [Storable]
+    private NormalDistributedRandom gauss;
+    [Storable]
+    private Individual[] solutions;
+    [Storable]
+    private double stepSizeLearningRate; //=cp learning rate in [0,1]
+    [Storable]
+    private double stepSizeDampeningFactor; //d
+    [Storable]
+    private double targetSuccessProbability;// p^target_succ
+    [Storable]
+    private double evolutionPathLearningRate;//cc
+    [Storable]
+    private double covarianceMatrixLearningRate;//ccov
+    [Storable]
+    private double covarianceMatrixUnlearningRate;
+    [Storable]
+    private double successThreshold; //ptresh
+
+    #endregion
+
+    #region ParameterNames
+    private const string MaximumRuntimeName = "Maximum Runtime";
+    private const string SeedName = "Seed";
+    private const string SetSeedRandomlyName = "SetSeedRandomly";
+    private const string PopulationSizeName = "PopulationSize";
+    private const string MaximumGenerationsName = "MaximumGenerations";
+    private const string MaximumEvaluatedSolutionsName = "MaximumEvaluatedSolutions";
+    private const string InitialSigmaName = "InitialSigma";
+    private const string IndicatorName = "Indicator";
+
+    private const string EvaluationsResultName = "Evaluations";
+    private const string IterationsResultName = "Generations";
+    private const string TimetableResultName = "Timetable";
+    private const string HypervolumeResultName = "Hypervolume";
+    private const string GenerationalDistanceResultName = "Generational Distance";
+    private const string InvertedGenerationalDistanceResultName = "Inverted Generational Distance";
+    private const string CrowdingResultName = "Crowding";
+    private const string SpacingResultName = "Spacing";
+    private const string CurrentFrontResultName = "Pareto Front";
+    private const string BestHypervolumeResultName = "Best Hypervolume";
+    private const string BestKnownHypervolumeResultName = "Best known hypervolume";
+    private const string DifferenceToBestKnownHypervolumeResultName = "Absolute Distance to BestKnownHypervolume";
+    private const string ScatterPlotResultName = "ScatterPlot";
+    #endregion
+
+    #region ParameterProperties
+    public IFixedValueParameter<IntValue> MaximumRuntimeParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumRuntimeName]; }
+    }
+    public IFixedValueParameter<IntValue> SeedParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[SeedName]; }
+    }
+    public FixedValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (FixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyName]; }
+    }
+    public IFixedValueParameter<IntValue> PopulationSizeParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[PopulationSizeName]; }
+    }
+    public IFixedValueParameter<IntValue> MaximumGenerationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumGenerationsName]; }
+    }
+    public IFixedValueParameter<IntValue> MaximumEvaluatedSolutionsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluatedSolutionsName]; }
+    }
+    public IValueParameter<DoubleArray> InitialSigmaParameter {
+      get { return (IValueParameter<DoubleArray>)Parameters[InitialSigmaName]; }
+    }
+    public IConstrainedValueParameter<IIndicator> IndicatorParameter {
+      get { return (IConstrainedValueParameter<IIndicator>)Parameters[IndicatorName]; }
+    }
+    #endregion
+
+    #region Properties
+    public int MaximumRuntime {
+      get { return MaximumRuntimeParameter.Value.Value; }
+      set { MaximumRuntimeParameter.Value.Value = value; }
+    }
+    public int Seed {
+      get { return SeedParameter.Value.Value; }
+      set { SeedParameter.Value.Value = value; }
+    }
+    public bool SetSeedRandomly {
+      get { return SetSeedRandomlyParameter.Value.Value; }
+      set { SetSeedRandomlyParameter.Value.Value = value; }
+    }
+    public int PopulationSize {
+      get { return PopulationSizeParameter.Value.Value; }
+      set { PopulationSizeParameter.Value.Value = value; }
+    }
+    public int MaximumGenerations {
+      get { return MaximumGenerationsParameter.Value.Value; }
+      set { MaximumGenerationsParameter.Value.Value = value; }
+    }
+    public int MaximumEvaluatedSolutions {
+      get { return MaximumEvaluatedSolutionsParameter.Value.Value; }
+      set { MaximumEvaluatedSolutionsParameter.Value.Value = value; }
+    }
+    public DoubleArray InitialSigma {
+      get { return InitialSigmaParameter.Value; }
+      set { InitialSigmaParameter.Value = value; }
+    }
+    public IIndicator Indicator {
+      get { return IndicatorParameter.Value; }
+      set { IndicatorParameter.Value = value; }
+    }
+
+    public double StepSizeLearningRate { get { return stepSizeLearningRate; } }
+    public double StepSizeDampeningFactor { get { return stepSizeDampeningFactor; } }
+    public double TargetSuccessProbability { get { return targetSuccessProbability; } }
+    public double EvolutionPathLearningRate { get { return evolutionPathLearningRate; } }
+    public double CovarianceMatrixLearningRate { get { return covarianceMatrixLearningRate; } }
+    public double CovarianceMatrixUnlearningRate { get { return covarianceMatrixUnlearningRate; } }
+    public double SuccessThreshold { get { return successThreshold; } }
+    #endregion
+
+    #region ResultsProperties
+    private int ResultsEvaluations {
+      get { return ((IntValue)Results[EvaluationsResultName].Value).Value; }
+      set { ((IntValue)Results[EvaluationsResultName].Value).Value = value; }
+    }
+    private int ResultsIterations {
+      get { return ((IntValue)Results[IterationsResultName].Value).Value; }
+      set { ((IntValue)Results[IterationsResultName].Value).Value = value; }
+    }
+    #region Datatable
+    private DataTable ResultsQualities {
+      get { return (DataTable)Results[TimetableResultName].Value; }
+    }
+    private DataRow ResultsBestHypervolumeDataLine {
+      get { return ResultsQualities.Rows[BestHypervolumeResultName]; }
+    }
+    private DataRow ResultsHypervolumeDataLine {
+      get { return ResultsQualities.Rows[HypervolumeResultName]; }
+    }
+    private DataRow ResultsGenerationalDistanceDataLine {
+      get { return ResultsQualities.Rows[GenerationalDistanceResultName]; }
+    }
+    private DataRow ResultsInvertedGenerationalDistanceDataLine {
+      get { return ResultsQualities.Rows[InvertedGenerationalDistanceResultName]; }
+    }
+    private DataRow ResultsCrowdingDataLine {
+      get { return ResultsQualities.Rows[CrowdingResultName]; }
+    }
+    private DataRow ResultsSpacingDataLine {
+      get { return ResultsQualities.Rows[SpacingResultName]; }
+    }
+    private DataRow ResultsHypervolumeDifferenceDataLine {
+      get { return ResultsQualities.Rows[DifferenceToBestKnownHypervolumeResultName]; }
+    }
+    #endregion
+    //QualityIndicators
+    private double ResultsHypervolume {
+      get { return ((DoubleValue)Results[HypervolumeResultName].Value).Value; }
+      set { ((DoubleValue)Results[HypervolumeResultName].Value).Value = value; }
+    }
+    private double ResultsGenerationalDistance {
+      get { return ((DoubleValue)Results[GenerationalDistanceResultName].Value).Value; }
+      set { ((DoubleValue)Results[GenerationalDistanceResultName].Value).Value = value; }
+    }
+    private double ResultsInvertedGenerationalDistance {
+      get { return ((DoubleValue)Results[InvertedGenerationalDistanceResultName].Value).Value; }
+      set { ((DoubleValue)Results[InvertedGenerationalDistanceResultName].Value).Value = value; }
+    }
+    private double ResultsCrowding {
+      get { return ((DoubleValue)Results[CrowdingResultName].Value).Value; }
+      set { ((DoubleValue)Results[CrowdingResultName].Value).Value = value; }
+    }
+    private double ResultsSpacing {
+      get { return ((DoubleValue)Results[SpacingResultName].Value).Value; }
+      set { ((DoubleValue)Results[SpacingResultName].Value).Value = value; }
+    }
+    private double ResultsBestHypervolume {
+      get { return ((DoubleValue)Results[BestHypervolumeResultName].Value).Value; }
+      set { ((DoubleValue)Results[BestHypervolumeResultName].Value).Value = value; }
+    }
+    private double ResultsBestKnownHypervolume {
+      get { return ((DoubleValue)Results[BestKnownHypervolumeResultName].Value).Value; }
+      set { ((DoubleValue)Results[BestKnownHypervolumeResultName].Value).Value = value; }
+    }
+    private double ResultsDifferenceBestKnownHypervolume {
+      get { return ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value; }
+      set { ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value = value; }
+
+    }
+    //Solutions
+    private DoubleMatrix ResultsSolutions {
+      get { return (DoubleMatrix)Results[CurrentFrontResultName].Value; }
+      set { Results[CurrentFrontResultName].Value = value; }
+    }
+    private ParetoFrontScatterPlot ResultsScatterPlot {
+      get { return (ParetoFrontScatterPlot)Results[ScatterPlotResultName].Value; }
+      set { Results[ScatterPlotResultName].Value = value; }
+    }
+    #endregion
+
+    #region Constructors
+    public MOCMAEvolutionStrategy() {
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumRuntimeName, "The maximum runtime in seconds after which the algorithm stops. Use -1 to specify no limit for the runtime", new IntValue(3600)));
+      Parameters.Add(new FixedValueParameter<IntValue>(SeedName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<IntValue>(PopulationSizeName, "λ (lambda) - the size of the offspring population.", new IntValue(20)));
+      Parameters.Add(new ValueParameter<DoubleArray>(InitialSigmaName, "The initial sigma can be a single value or a value for each dimension. All values need to be > 0.", new DoubleArray(new[] { 0.5 })));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumGenerationsName, "The maximum number of generations which should be processed.", new IntValue(1000)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluatedSolutionsName, "The maximum number of evaluated solutions that should be computed.", new IntValue(int.MaxValue)));
+      var set = new ItemSet<IIndicator> { new HypervolumeIndicator(), new CrowdingIndicator(), new MinimalDistanceIndicator() };
+      Parameters.Add(new ConstrainedValueParameter<IIndicator>(IndicatorName, "The selection mechanism on non-dominated solutions", set, set.First()));
+    }
+
+    [StorableConstructor]
+    protected MOCMAEvolutionStrategy(bool deserializing) : base(deserializing) { }
+
+    protected MOCMAEvolutionStrategy(MOCMAEvolutionStrategy original, Cloner cloner) : base(original, cloner) {
+      random = cloner.Clone(original.random);
+      gauss = cloner.Clone(original.gauss);
+      solutions = original.solutions != null ? original.solutions.Select(cloner.Clone).ToArray() : null;
+      stepSizeLearningRate = original.stepSizeLearningRate;
+      stepSizeDampeningFactor = original.stepSizeDampeningFactor;
+      targetSuccessProbability = original.targetSuccessProbability;
+      evolutionPathLearningRate = original.evolutionPathLearningRate;
+      covarianceMatrixLearningRate = original.covarianceMatrixLearningRate;
+      covarianceMatrixUnlearningRate = original.covarianceMatrixUnlearningRate;
+      successThreshold = original.successThreshold;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) { return new MOCMAEvolutionStrategy(this, cloner); }
+    #endregion
+
+    #region Initialization
+    protected override void Initialize(CancellationToken cancellationToken) {
+      if (SetSeedRandomly) Seed = new System.Random().Next();
+      random.Reset(Seed);
+      gauss = new NormalDistributedRandom(random, 0, 1);
+
+      InitResults();
+      InitStrategy();
+      InitSolutions();
+      Analyze();
+
+      ResultsIterations = 1;
+    }
+    private Individual InitializeIndividual(RealVector x) {
+      var zeros = new RealVector(x.Length);
+      var c = new double[x.Length, x.Length];
+      var sigma = InitialSigma.Max();
+      for (var i = 0; i < x.Length; i++) {
+        var d = InitialSigma[i % InitialSigma.Length] / sigma;
+        c[i, i] = d * d;
+      }
+      return new Individual(x, targetSuccessProbability, sigma, zeros, c, this);
+    }
+    private void InitSolutions() {
+      solutions = new Individual[PopulationSize];
+      for (var i = 0; i < PopulationSize; i++) {
+        var x = new RealVector(Problem.Encoding.Length); // Uniform distibution in all dimensions assumed.
+        var bounds = Problem.Encoding.Bounds;
+        for (var j = 0; j < Problem.Encoding.Length; j++) {
+          var dim = j % bounds.Rows;
+          x[j] = random.NextDouble() * (bounds[dim, 1] - bounds[dim, 0]) + bounds[dim, 0];
+        }
+        solutions[i] = InitializeIndividual(x);
+        PenalizeEvaluate(solutions[i]);
+      }
+      ResultsEvaluations += solutions.Length;
+    }
+    private void InitStrategy() {
+      const int lambda = 1;
+      double n = Problem.Encoding.Length;
+      targetSuccessProbability = 1.0 / (5.0 + Math.Sqrt(lambda) / 2.0);
+      stepSizeDampeningFactor = 1.0 + n / (2.0 * lambda);
+      stepSizeLearningRate = targetSuccessProbability * lambda / (2.0 + targetSuccessProbability * lambda);
+      evolutionPathLearningRate = 2.0 / (n + 2.0);
+      covarianceMatrixLearningRate = 2.0 / (n * n + 6.0);
+      covarianceMatrixUnlearningRate = 0.4 / (Math.Pow(n, 1.6) + 1);
+      successThreshold = 0.44;
+    }
+    private void InitResults() {
+      Results.Add(new Result(IterationsResultName, "The number of gererations evaluated", new IntValue(0)));
+      Results.Add(new Result(EvaluationsResultName, "The number of function evaltions performed", new IntValue(0)));
+      Results.Add(new Result(HypervolumeResultName, "The hypervolume of the current front considering the Referencepoint defined in the Problem", new DoubleValue(0.0)));
+      Results.Add(new Result(BestHypervolumeResultName, "The best hypervolume of the current run considering the Referencepoint defined in the Problem", new DoubleValue(0.0)));
+      Results.Add(new Result(BestKnownHypervolumeResultName, "The best knwon hypervolume considering the Referencepoint defined in the Problem", new DoubleValue(double.NaN)));
+      Results.Add(new Result(DifferenceToBestKnownHypervolumeResultName, "The difference between the current and the best known hypervolume", new DoubleValue(double.NaN)));
+      Results.Add(new Result(GenerationalDistanceResultName, "The generational distance to an optimal pareto front defined in the Problem", new DoubleValue(double.NaN)));
+      Results.Add(new Result(InvertedGenerationalDistanceResultName, "The inverted generational distance to an optimal pareto front defined in the Problem", new DoubleValue(double.NaN)));
+      Results.Add(new Result(CrowdingResultName, "The average crowding value for the current front (excluding infinities)", new DoubleValue(0.0)));
+      Results.Add(new Result(SpacingResultName, "The spacing for the current front (excluding infinities)", new DoubleValue(0.0)));
+
+      var table = new DataTable("QualityIndicators");
+      table.Rows.Add(new DataRow(BestHypervolumeResultName));
+      table.Rows.Add(new DataRow(HypervolumeResultName));
+      table.Rows.Add(new DataRow(CrowdingResultName));
+      table.Rows.Add(new DataRow(GenerationalDistanceResultName));
+      table.Rows.Add(new DataRow(InvertedGenerationalDistanceResultName));
+      table.Rows.Add(new DataRow(DifferenceToBestKnownHypervolumeResultName));
+      table.Rows.Add(new DataRow(SpacingResultName));
+      Results.Add(new Result(TimetableResultName, "Different quality meassures in a timeseries", table));
+      Results.Add(new Result(CurrentFrontResultName, "The current front", new DoubleMatrix()));
+      Results.Add(new Result(ScatterPlotResultName, "A scatterplot displaying the evaluated solutions and (if available) the analytically optimal front", new ParetoFrontScatterPlot()));
+
+      var problem = Problem as MultiObjectiveTestFunctionProblem;
+      if (problem == null) return;
+      if (problem.BestKnownFront != null) {
+        ResultsBestKnownHypervolume = Hypervolume.Calculate(problem.BestKnownFront.ToJaggedArray(), problem.TestFunction.ReferencePoint(problem.Objectives), Problem.Maximization);
+        ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume;
+      }
+      ResultsScatterPlot = new ParetoFrontScatterPlot(new double[0][], new double[0][], problem.BestKnownFront.ToJaggedArray(), problem.Objectives, problem.ProblemSize);
+    }
+    #endregion
+
+    #region Mainloop
+    protected override void Run(CancellationToken cancellationToken) {
+      while (ResultsIterations < MaximumGenerations) {
+        try {
+          Iterate();
+          ResultsIterations++;
+          cancellationToken.ThrowIfCancellationRequested();
+        } finally {
+          Analyze();
+        }
+      }
+    }
+    private void Iterate() {
+      var offspring = solutions.Select(i => {
+        var o = new Individual(i);
+        o.Mutate(gauss);
+        PenalizeEvaluate(o);
+        return o;
+      });
+      ResultsEvaluations += solutions.Length;
+      var parents = solutions.Concat(offspring).ToArray();
+      SelectParents(parents, solutions.Length);
+      UpdatePopulation(parents);
+    }
+    protected override void OnExecutionTimeChanged() {
+      base.OnExecutionTimeChanged();
+      if (CancellationTokenSource == null) return;
+      if (MaximumRuntime == -1) return;
+      if (ExecutionTime.TotalSeconds > MaximumRuntime) CancellationTokenSource.Cancel();
+    }
+    #endregion
+
+    #region Evaluation
+    private void PenalizeEvaluate(Individual individual) {
+      if (IsFeasable(individual.Mean)) {
+        individual.Fitness = Evaluate(individual.Mean);
+        individual.PenalizedFitness = individual.Fitness;
+      } else {
+        var t = ClosestFeasible(individual.Mean);
+        individual.Fitness = Evaluate(t);
+        individual.PenalizedFitness = Penalize(individual.Mean, t, individual.Fitness);
+      }
+    }
+    private double[] Evaluate(RealVector x) {
+      var res = Problem.Evaluate(new SingleEncodingIndividual(Problem.Encoding, new Scope { Variables = { new Variable(Problem.Encoding.Name, x) } }), random);
+      return res;
+    }
+    private double[] Penalize(RealVector x, RealVector t, IEnumerable<double> fitness) {
+      var penalty = x.Zip(t, (a, b) => (a - b) * (a - b)).Sum() * 1E-6;
+      return fitness.Select((v, i) => Problem.Maximization[i] ? v - penalty : v + penalty).ToArray();
+    }
+    private RealVector ClosestFeasible(RealVector x) {
+      var bounds = Problem.Encoding.Bounds;
+      var r = new RealVector(x.Length);
+      for (var i = 0; i < x.Length; i++) {
+        var dim = i % bounds.Rows;
+        r[i] = Math.Min(Math.Max(bounds[dim, 0], x[i]), bounds[dim, 1]);
+      }
+      return r;
+    }
+    private bool IsFeasable(RealVector offspring) {
+      var bounds = Problem.Encoding.Bounds;
+      for (var i = 0; i < offspring.Length; i++) {
+        var dim = i % bounds.Rows;
+        if (bounds[dim, 0] > offspring[i] || offspring[i] > bounds[dim, 1]) return false;
+      }
+      return true;
+    }
+    #endregion
+
+    private void SelectParents(IReadOnlyList<Individual> parents, int length) {
+      //perform a nondominated sort to assign the rank to every element
+      int[] ranks;
+      var fronts = DominationCalculator<Individual>.CalculateAllParetoFronts(parents.ToArray(), parents.Select(i => i.PenalizedFitness).ToArray(), Problem.Maximization, out ranks);
+
+      //deselect the highest rank fronts until we would end up with less or equal mu elements
+      var rank = fronts.Count - 1;
+      var popSize = parents.Count;
+      while (popSize - fronts[rank].Count >= length) {
+        var front = fronts[rank];
+        foreach (var i in front) i.Item1.Selected = false;
+        popSize -= front.Count;
+        rank--;
+      }
+
+      //now use the indicator to deselect the approximatingly worst elements of the last selected front
+      var front1 = fronts[rank].OrderBy(x => x.Item1.PenalizedFitness[0]).ToList();
+      for (; popSize > length; popSize--) {
+        var lc = Indicator.LeastContributer(front1.Select(i => i.Item1).ToArray(), Problem);
+        front1[lc].Item1.Selected = false;
+        front1.Swap(lc, front1.Count - 1);
+        front1.RemoveAt(front1.Count - 1);
+      }
+    }
+
+    private void UpdatePopulation(IReadOnlyList<Individual> parents) {
+      foreach (var p in parents.Skip(solutions.Length).Where(i => i.Selected))
+        p.UpdateAsOffspring();
+      for (var i = 0; i < solutions.Length; i++)
+        if (parents[i].Selected)
+          parents[i].UpdateAsParent(parents[i + solutions.Length].Selected);
+      solutions = parents.Where(p => p.Selected).ToArray();
+    }
+
+    private void Analyze() {
+      ResultsScatterPlot = new ParetoFrontScatterPlot(solutions.Select(x => x.Fitness).ToArray(), solutions.Select(x => x.Mean.ToArray()).ToArray(), ResultsScatterPlot.ParetoFront, ResultsScatterPlot.Objectives, ResultsScatterPlot.ProblemSize);
+      ResultsSolutions = solutions.Select(x => x.Mean.ToArray()).ToMatrix();
+
+      var problem = Problem as MultiObjectiveTestFunctionProblem;
+      if (problem == null) return;
+
+      var front = NonDominatedSelect.GetDominatingVectors(solutions.Select(x => x.Fitness), problem.ReferencePoint.CloneAsArray(), Problem.Maximization, true).ToArray();
+      if (front.Length == 0) return;
+      var bounds = problem.Bounds.CloneAsMatrix();
+      ResultsCrowding = Crowding.Calculate(front, bounds);
+      ResultsSpacing = Spacing.Calculate(front);
+      ResultsGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistance.Calculate(front, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
+      ResultsInvertedGenerationalDistance = problem.BestKnownFront != null ? InvertedGenerationalDistance.Calculate(front, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
+      ResultsHypervolume = Hypervolume.Calculate(front, problem.ReferencePoint.CloneAsArray(), Problem.Maximization);
+      ResultsBestHypervolume = Math.Max(ResultsHypervolume, ResultsBestHypervolume);
+      ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume - ResultsBestHypervolume;
+
+      ResultsBestHypervolumeDataLine.Values.Add(ResultsBestHypervolume);
+      ResultsHypervolumeDataLine.Values.Add(ResultsHypervolume);
+      ResultsCrowdingDataLine.Values.Add(ResultsCrowding);
+      ResultsGenerationalDistanceDataLine.Values.Add(ResultsGenerationalDistance);
+      ResultsInvertedGenerationalDistanceDataLine.Values.Add(ResultsInvertedGenerationalDistance);
+      ResultsSpacingDataLine.Values.Add(ResultsSpacing);
+      ResultsHypervolumeDifferenceDataLine.Values.Add(ResultsDifferenceBestKnownHypervolume);
+
+      Problem.Analyze(
+        solutions.Select(x => (Optimization.Individual)new SingleEncodingIndividual(Problem.Encoding, new Scope { Variables = { new Variable(Problem.Encoding.Name, x.Mean) } })).ToArray(),
+        solutions.Select(x => x.Fitness).ToArray(),
+        Results,
+        random);
+    }
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Plugin.cs.frame	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Plugin.cs.frame	(revision 15244)
@@ -0,0 +1,44 @@
+#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.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Algorithms.EvolutionStrategy plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Algorithms.MOCMAEvolutionStrategy", "3.3.14.$WCREV$")]
+  [PluginFile("HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.7")]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.TestFunctions.MultiObjective", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabAlgorithmsMOCMAEvolutionStrategyPlugin : PluginBase {
+  }
+}
Index: /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Properties/AssemblyInfo.cs.frame	(revision 15244)
+++ /stable/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Properties/AssemblyInfo.cs.frame	(revision 15244)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Algorithms.MOCMAEvolutionStrategy")]
+[assembly: AssemblyDescription("HeuristicLab implementation of Multi-Objective CMA Evolution Strategy (MO-CMA-ES)")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c27ab3d3-44d4-44e8-a3cd-3cea09d19a8f")]
+
+// 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 Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.14.$WCREV$")]
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 15244)
@@ -37,6 +37,6 @@
     }
 
-    public IResultParameter<ScatterPlotContent> ScatterPlotResultParameter {
-      get { return (IResultParameter<ScatterPlotContent>)Parameters["Scatterplot"]; }
+    public IResultParameter<ParetoFrontScatterPlot> ScatterPlotResultParameter {
+      get { return (IResultParameter<ParetoFrontScatterPlot>)Parameters["Scatterplot"]; }
     }
 
@@ -51,5 +51,5 @@
     public ScatterPlotAnalyzer() {
       Parameters.Add(new ScopeTreeLookupParameter<RealVector>("Individuals", "The individual solutions to the problem"));
-      Parameters.Add(new ResultParameter<ScatterPlotContent>("Scatterplot", "The scatterplot for the current and optimal (if known front)"));
+      Parameters.Add(new ResultParameter<ParetoFrontScatterPlot>("Scatterplot", "The scatterplot for the current and optimal (if known front)"));
 
     }
@@ -57,7 +57,8 @@
     public override IOperation Apply() {
       var qualities = QualitiesParameter.ActualValue;
+      var individuals = IndividualsParameter.ActualValue;
       var testFunction = TestFunctionParameter.ActualValue;
       int objectives = qualities[0].Length;
-      var individuals = IndividualsParameter.ActualValue;
+      int problemSize = individuals[0].Length;
 
       double[][] optimalFront = new double[0][];
@@ -68,5 +69,5 @@
       var solutionClones = individuals.Select(s => s.ToArray()).ToArray();
 
-      ScatterPlotResultParameter.ActualValue = new ScatterPlotContent(qualityClones, solutionClones, optimalFront, objectives);
+      ScatterPlotResultParameter.ActualValue = new ParetoFrontScatterPlot(qualityClones, solutionClones, optimalFront, objectives, problemSize);
 
       return base.Apply();
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 15244)
@@ -111,5 +111,5 @@
     <Compile Include="Calculators\InvertedGenerationalDistance.cs" />
     <Compile Include="Calculators\GenerationalDistance.cs" />
-    <Compile Include="ScatterPlotContent.cs" />
+    <Compile Include="ParetoFrontScatterPlot.cs" />
     <Compile Include="Utilities.cs" />
     <Compile Include="Instances\MISCInstanceProvider.cs" />
@@ -179,4 +179,9 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
       <Project>{a9ad58b9-3ef9-4cc1-97e5-8d909039ff5c}</Project>
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs	(revision 15244)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ParetoFrontScatterPlot.cs	(revision 15244)
@@ -0,0 +1,93 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
+  [StorableClass]
+  [Item("Pareto Front Scatter Plot", "The optimal front, current front and its associated Points in the searchspace")]
+  public class ParetoFrontScatterPlot : Item {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+    }
+
+    [Storable]
+    private int objectives;
+    public int Objectives {
+      get { return objectives; }
+    }
+
+    [Storable]
+    private int problemSize;
+    public int ProblemSize {
+      get { return problemSize; }
+    }
+
+    [Storable]
+    private double[][] qualities;
+    public double[][] Qualities {
+      get { return qualities; }
+    }
+
+    [Storable]
+    private double[][] solutions;
+    public double[][] Solutions {
+      get { return solutions; }
+    }
+
+    [Storable]
+    private double[][] paretoFront;
+    public double[][] ParetoFront {
+      get { return paretoFront; }
+    }
+
+    #region Constructor, Cloning & Persistance
+    public ParetoFrontScatterPlot(double[][] qualities, double[][] solutions, double[][] paretoFront, int objectives, int problemSize) {
+      this.qualities = qualities;
+      this.solutions = solutions;
+      this.paretoFront = paretoFront;
+      this.objectives = objectives;
+      this.problemSize = problemSize;
+    }
+    public ParetoFrontScatterPlot() { }
+
+    protected ParetoFrontScatterPlot(ParetoFrontScatterPlot original, Cloner cloner)
+      : base(original, cloner) {
+      if (original.qualities != null) qualities = original.qualities.Select(s => s.ToArray()).ToArray();
+      if (original.solutions != null) solutions = original.solutions.Select(s => s.ToArray()).ToArray();
+      if (original.paretoFront != null) paretoFront = original.paretoFront.Select(s => s.ToArray()).ToArray();
+      objectives = original.objectives;
+      problemSize = original.problemSize;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParetoFrontScatterPlot(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected ParetoFrontScatterPlot(bool deserializing)
+      : base(deserializing) { }
+    #endregion
+  }
+}
Index: /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Plugin.cs.frame	(revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Plugin.cs.frame	(revision 15244)
@@ -25,5 +25,6 @@
   [Plugin("HeuristicLab.Problems.TestFunctions.MultiObjective", "3.3.14.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.Collections", "3.3")] 
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
   [PluginDependency("HeuristicLab.Core", "3.3")]  
Index: able/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ScatterPlotContent.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/ScatterPlotContent.cs	(revision 15243)
+++ 	(revision )
@@ -1,101 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
-  [StorableClass]
-  [Item("ScatterPlot", "The optimal front, current front and its associated Points in the searchspace")]
-  public class ScatterPlotContent : Item {
-
-    [Storable]
-    private double[][] qualities;
-    public double[][] Qualities {
-      get {
-        return qualities;
-      }
-
-      private set {
-        qualities = value;
-      }
-    }
-
-    [Storable]
-    private int objectives;
-    public int Objectives {
-      get {
-        return objectives;
-      }
-
-      private set {
-        objectives = value;
-      }
-    }
-
-    [Storable]
-    private double[][] solutions;
-    public double[][] Solutions {
-      get {
-        return solutions;
-      }
-
-      private set {
-        solutions = value;
-      }
-    }
-
-    [Storable]
-    private double[][] paretoFront;
-    public double[][] ParetoFront {
-      get {
-        return paretoFront;
-      }
-
-      private set {
-        paretoFront = value;
-      }
-    }
-
-    [StorableConstructor]
-    protected ScatterPlotContent(bool deserializing) : base() { }
-
-    protected ScatterPlotContent(ScatterPlotContent original, Cloner cloner)
-      : this() {
-      this.qualities = original.qualities.Select(s => s.ToArray()).ToArray();
-      this.solutions = original.solutions.Select(s => s.ToArray()).ToArray();
-      this.paretoFront = original.paretoFront.Select(s => s.ToArray()).ToArray();
-      this.objectives = original.objectives;
-    }
-    protected ScatterPlotContent() : base() { }
-    public ScatterPlotContent(double[][] qualities, double[][] solutions, double[][] paretoFront, int objectives) {
-      this.qualities = qualities;
-      this.solutions = solutions;
-      this.paretoFront = paretoFront;
-      this.objectives = objectives;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ScatterPlotContent(this, cloner);
-    }
-  }
-}
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj	(revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/HeuristicLab.Problems.TestFunctions.Views-3.3.csproj	(revision 15244)
@@ -105,20 +105,11 @@
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Windows.Forms.DataVisualization" />
-    <Reference Include="System.Xml.Linq">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Data.DataSetExtensions">
-      <RequiredTargetFramework>3.5</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs">
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ParetoFrontScatterPlotView.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs">
-      <DependentUpon>MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs</DependentUpon>
+    <Compile Include="ParetoFrontScatterPlotView.Designer.cs">
+      <DependentUpon>ParetoFrontScatterPlotView.cs</DependentUpon>
     </Compile>
     <Compile Include="Plugin.cs" />
@@ -143,4 +134,14 @@
   </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.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
       <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
@@ -211,9 +212,4 @@
       <Project>{88B9B0E3-344E-4196-82A3-0F9732506FE8}</Project>
       <Name>HeuristicLab.Problems.TestFunctions-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Visualization.ChartControlsExtensions\3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj">
-      <Project>{315bda09-3f4f-49b3-9790-b37cfc1c5750}</Project>
-      <Name>HeuristicLab.Visualization.ChartControlsExtensions-3.3</Name>
       <Private>False</Private>
     </ProjectReference>
Index: able/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.Designer.cs	(revision 15243)
+++ 	(revision )
@@ -1,137 +1,0 @@
-﻿#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.Problems.TestFunctions.Views {
-  partial class MultiObjectiveTestFunctionParetoFrontScatterPlotView {
-    /// <summary> 
-    /// Required designer variable.
-    /// </summary>
-    private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Component Designer generated code
-
-    /// <summary> 
-    /// Required method for Designer support - do not modify 
-    /// the contents of this method with the code editor.
-    /// </summary>
-    private void InitializeComponent() {
-      this.components = new System.ComponentModel.Container();
-      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
-      System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend();
-      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
-      this.menuStrip1 = new System.Windows.Forms.MenuStrip();
-      this.chooseDimensionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-      this.chooseYDimensionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-      this.testToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
-      this.menuStrip1.SuspendLayout();
-      this.SuspendLayout();
-      // 
-      // chart
-      // 
-      chartArea2.Name = "ChartArea";
-      this.chart.ChartAreas.Add(chartArea2);
-      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
-      legend2.Alignment = System.Drawing.StringAlignment.Center;
-      legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
-      legend2.Name = "Default";
-      this.chart.Legends.Add(legend2);
-      this.chart.Location = new System.Drawing.Point(0, 42);
-      this.chart.Margin = new System.Windows.Forms.Padding(6);
-      this.chart.Name = "chart";
-      this.chart.Size = new System.Drawing.Size(1054, 712);
-      this.chart.TabIndex = 1;
-      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
-      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
-      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
-      // 
-      // menuStrip1
-      // 
-      this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32);
-      this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.chooseDimensionToolStripMenuItem,
-            this.chooseYDimensionToolStripMenuItem});
-      this.menuStrip1.Location = new System.Drawing.Point(0, 0);
-      this.menuStrip1.Name = "menuStrip1";
-      this.menuStrip1.Size = new System.Drawing.Size(1054, 42);
-      this.menuStrip1.TabIndex = 2;
-      this.menuStrip1.Text = "menuStrip1";
-      this.menuStrip1.ShowItemToolTips = true;
-      // 
-      // chooseDimensionToolStripMenuItem
-      // 
-      this.chooseDimensionToolStripMenuItem.Name = "chooseDimensionToolStripMenuItem";
-      this.chooseDimensionToolStripMenuItem.Size = new System.Drawing.Size(253, 38);
-      this.chooseDimensionToolStripMenuItem.Text = "Objective 0";
-      this.chooseDimensionToolStripMenuItem.ToolTipText = "Choose X-Dimension";
-      // 
-      // chooseYDimensionToolStripMenuItem
-      // 
-      this.chooseYDimensionToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.testToolStripMenuItem});
-      this.chooseYDimensionToolStripMenuItem.Name = "chooseYDimensionToolStripMenuItem";
-      this.chooseYDimensionToolStripMenuItem.Size = new System.Drawing.Size(252, 38);
-      this.chooseYDimensionToolStripMenuItem.Text = "Objective 1";
-      this.chooseYDimensionToolStripMenuItem.ToolTipText = "Choose Y-Dimension";
-      // 
-      // testToolStripMenuItem
-      // 
-      this.testToolStripMenuItem.Name = "testToolStripMenuItem";
-      this.testToolStripMenuItem.Size = new System.Drawing.Size(269, 38);
-      this.testToolStripMenuItem.Text = "Test";
-      // 
-      // MOQualitiesScatterPlotView
-      // 
-      this.AllowDrop = true;
-      this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
-      this.Controls.Add(this.chart);
-      this.Controls.Add(this.menuStrip1);
-      this.Margin = new System.Windows.Forms.Padding(6);
-      this.Name = "MOQualitiesScatterPlotView";
-      this.Size = new System.Drawing.Size(1054, 754);
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
-      this.menuStrip1.ResumeLayout(false);
-      this.menuStrip1.PerformLayout();
-      this.ResumeLayout(false);
-      this.PerformLayout();
-
-    }
-
-    #endregion
-
-    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
-    private System.Windows.Forms.MenuStrip menuStrip1;
-    private System.Windows.Forms.ToolStripMenuItem chooseDimensionToolStripMenuItem;
-    private System.Windows.Forms.ToolStripMenuItem chooseYDimensionToolStripMenuItem;
-    private System.Windows.Forms.ToolStripMenuItem testToolStripMenuItem;
-  }
-}
Index: able/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/MultiObjectiveTestFunctionParetoFrontScatterPlotView.cs	(revision 15243)
+++ 	(revision )
@@ -1,359 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-using System;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Windows.Forms;
-using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Core.Views;
-using HeuristicLab.MainForm;
-using HeuristicLab.Problems.TestFunctions.MultiObjective;
-
-namespace HeuristicLab.Problems.TestFunctions.Views {
-  [View("Scatter Plot")]
-  [Content(typeof(ScatterPlotContent))]
-  public partial class MultiObjectiveTestFunctionParetoFrontScatterPlotView : ItemView {
-    private const string QUALITIES = "Qualities";
-    private const string PARETO_FRONT = "Best Known Pareto Front";
-    private Series qualitySeries;
-    private Series paretoSeries;
-    private int xDim = 0;
-    private int yDim = 1;
-    int objectives = -1;
-
-    public new ScatterPlotContent Content {
-      get { return (ScatterPlotContent)base.Content; }
-      set { base.Content = value; }
-    }
-
-    public MultiObjectiveTestFunctionParetoFrontScatterPlotView()
-      : base() {
-      InitializeComponent();
-
-      BuildEmptySeries();
-
-      //start with qualities toggled ON
-      qualitySeries.Points.AddXY(0, 0);
-
-      this.chart.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
-      this.chart.AxisViewChanged += new EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(chart_AxisViewChanged);
-      this.chart.GetToolTipText += new System.EventHandler<ToolTipEventArgs>(this.Chart_GetToolTipText);
-
-      //configure axis 
-      this.chart.CustomizeAllChartAreas();
-      this.chart.ChartAreas[0].AxisX.Title = "Objective " + xDim;
-      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
-      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].CursorX.Interval = 1;
-      this.chart.ChartAreas[0].CursorY.Interval = 1;
-
-      this.chart.ChartAreas[0].AxisY.Title = "Objective " + yDim;
-      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
-      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
-    }
-
-
-    private void Chart_GetToolTipText(object sender, ToolTipEventArgs e) {
-      if (e.HitTestResult.ChartElementType == ChartElementType.LegendItem) {
-        if (e.HitTestResult.Series == paretoSeries && (Content.ParetoFront == null || Content.ParetoFront.Length == 0)) {
-          e.Text = "No optimal pareto front is available for this problem with this number of objectives";
-        }
-        if (e.HitTestResult.Series == paretoSeries && (xDim >= Content.Objectives || yDim >= Content.Objectives)) {
-          e.Text = "The optimal pareto front can only be displayed in  Objective Space";
-        }
-      }
-
-      // Check selected chart element and set tooltip text
-      if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) {
-        int i = e.HitTestResult.PointIndex;
-        StringBuilder toolTippText = new StringBuilder();
-        DataPoint qp = e.HitTestResult.Series.Points[i];
-        toolTippText.Append("Objective " + xDim + " = " + qp.XValue + "\n");
-        toolTippText.Append("Objective " + yDim + " = " + qp.YValues[0]);
-
-        Series s = e.HitTestResult.Series;
-        if (s.Equals(this.chart.Series[QUALITIES])) {
-          double[] dp = Content.Solutions[i];
-          toolTippText.Append("\nSolution: {");
-          for (int j = 0; j < dp.Length; j++) {
-            toolTippText.Append(dp[j]);
-            toolTippText.Append(";");
-          }
-          toolTippText.Remove(toolTippText.Length - 1, 1);
-          toolTippText.Append("}");
-          e.Text = toolTippText.ToString();
-        }
-
-
-      }
-    }
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      if (Content == null) return;
-      if (objectives != Content.Objectives) {
-        AddMenuItems();
-        objectives = Content.Objectives;
-      }
-      if (Content.ParetoFront == null && chart.Series.Contains(paretoSeries)) {
-        Series s = this.chart.Series[PARETO_FRONT];
-        paretoSeries = null;
-        this.chart.Series.Remove(s);
-
-      } else if (Content.ParetoFront != null && !chart.Series.Contains(paretoSeries)) {
-        this.chart.Series.Add(PARETO_FRONT);
-        paretoSeries = this.chart.Series[PARETO_FRONT];
-        this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;
-        this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;
-      }
-      UpdateChart();
-    }
-
-    private void UpdateChart() {
-      if (InvokeRequired) Invoke((Action)UpdateChart);
-      else {
-        if (Content != null) {
-          this.UpdateSeries();
-          if (!this.chart.Series.Any(s => s.Points.Count > 0))
-            this.ClearChart();
-        }
-      }
-    }
-
-    private void UpdateCursorInterval() {
-      var estimatedValues = this.chart.Series[QUALITIES].Points.Select(x => x.XValue).DefaultIfEmpty(1.0);
-      var targetValues = this.chart.Series[QUALITIES].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
-      double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
-      double targetValuesRange = targetValues.Max() - targetValues.Min();
-      double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
-      double digits = (int)Math.Log10(interestingValuesRange) - 3;
-      double zoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
-      this.chart.ChartAreas[0].CursorX.Interval = zoomInterval;
-      this.chart.ChartAreas[0].CursorY.Interval = zoomInterval;
-
-      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = zoomInterval;
-      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = zoomInterval;
-
-      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
-      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = zoomInterval;
-      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
-      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSize = zoomInterval;
-
-      if (digits < 0) {
-        this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F" + (int)Math.Abs(digits);
-        this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F" + (int)Math.Abs(digits);
-      } else {
-        this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F0";
-        this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F0";
-      }
-    }
-
-    private void UpdateSeries() {
-      if (InvokeRequired) Invoke((Action)UpdateSeries);
-      else {
-
-        if (this.chart.Series.Contains(qualitySeries) && qualitySeries.Points.Count() != 0) {
-          FillSeries(Content.Qualities, Content.Solutions, qualitySeries);
-        }
-        if (this.chart.Series.Contains(paretoSeries) && paretoSeries.Points.Count() != 0) {
-          FillSeries(Content.ParetoFront, null, paretoSeries);
-        }
-
-
-        double minX = Double.MaxValue;
-        double maxX = Double.MinValue;
-        double minY = Double.MaxValue;
-        double maxY = Double.MinValue;
-        foreach (Series s in this.chart.Series) {
-          if (s.Points.Count == 0) continue;
-          minX = Math.Min(minX, s.Points.Select(p => p.XValue).Min());
-          maxX = Math.Max(maxX, s.Points.Select(p => p.XValue).Max());
-          minY = Math.Min(minY, s.Points.Select(p => p.YValues.Min()).Min());
-          maxY = Math.Max(maxY, s.Points.Select(p => p.YValues.Max()).Max());
-        }
-
-        maxX = maxX + 0.2 * Math.Abs(maxX);
-        minX = minX - 0.2 * Math.Abs(minX);
-        maxY = maxY + 0.2 * Math.Abs(maxY);
-        minY = minY - 0.2 * Math.Abs(minY);
-
-        double interestingValuesRangeX = maxX - minX;
-        double interestingValuesRangeY = maxY - minY;
-
-        int digitsX = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeX));
-        int digitsY = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRangeY));
-
-
-        maxX = Math.Round(maxX, digitsX);
-        minX = Math.Round(minX, digitsX);
-        maxY = Math.Round(maxY, digitsY);
-        minY = Math.Round(minY, digitsY);
-        if (minX > maxX) {
-          minX = 0;
-          maxX = 1;
-        }
-        if (minY > maxY) {
-          minY = 0;
-          maxY = 1;
-        }
-
-
-        this.chart.ChartAreas[0].AxisX.Maximum = maxX;
-        this.chart.ChartAreas[0].AxisX.Minimum = minX;
-        this.chart.ChartAreas[0].AxisY.Maximum = maxY;
-        this.chart.ChartAreas[0].AxisY.Minimum = minY;
-        UpdateCursorInterval();
-      }
-    }
-
-    private void ClearChart() {
-      if (chart.Series.Contains(qualitySeries)) chart.Series.Remove(qualitySeries);
-      if (chart.Series.Contains(paretoSeries)) chart.Series.Remove(paretoSeries);
-      BuildEmptySeries();
-    }
-
-    private void ToggleSeriesData(Series series) {
-      if (series.Points.Count > 0) {  //checks if series is shown
-        series.Points.Clear();
-      } else if (Content != null) {
-        switch (series.Name) {
-          case PARETO_FRONT:
-            FillSeries(Content.ParetoFront, null, this.chart.Series[PARETO_FRONT]);
-            break;
-          case QUALITIES:
-            FillSeries(Content.Qualities, Content.Solutions, this.chart.Series[QUALITIES]);
-            break;
-        }
-      }
-    }
-
-    private void chart_MouseDown(object sender, MouseEventArgs e) {
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType == ChartElementType.LegendItem) {
-        this.ToggleSeriesData(result.Series);
-      }
-
-    }
-
-    private void chart_MouseMove(object sender, MouseEventArgs e) {
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType == ChartElementType.LegendItem)
-        this.Cursor = Cursors.Hand;
-      else
-        this.Cursor = Cursors.Default;
-    }
-
-    private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {
-      this.chart.ChartAreas[0].AxisX.ScaleView.Size = e.NewSize;
-      this.chart.ChartAreas[0].AxisY.ScaleView.Size = e.NewSize;
-    }
-
-    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
-      if (this.chart.Series.Contains(qualitySeries)) e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[QUALITIES].Points.Count == 0 ? Color.Gray : Color.Black;
-      if (this.chart.Series.Contains(paretoSeries)) e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[PARETO_FRONT].Points.Count == 0 ? Color.Gray : Color.Black;
-    }
-
-    private void AddMenuItems() {
-      chooseDimensionToolStripMenuItem.DropDownItems.Clear();
-      chooseYDimensionToolStripMenuItem.DropDownItems.Clear();
-      if (Content == null) { return; }
-      int i = 0;
-      for (; i < Content.Objectives; i++) {
-        //add Menu Points
-        ToolStripMenuItem xItem = MakeMenuItem("X", "Objective " + i, i);
-        ToolStripMenuItem yItem = MakeMenuItem("Y", "Objective " + i, i);
-        xItem.Click += new System.EventHandler(this.XMenu_Click);
-        yItem.Click += new System.EventHandler(this.YMenu_Click);
-        chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);
-        chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);
-      }
-
-      for (; i < Content.Solutions[0].Length + Content.Objectives; i++) {
-        ToolStripMenuItem xItem = MakeMenuItem("X", "ProblemDimension " + (i - Content.Objectives), i);
-        ToolStripMenuItem yItem = MakeMenuItem("Y", "ProblemDimension " + (i - Content.Objectives), i); ;
-        xItem.Click += new System.EventHandler(this.XMenu_Click);
-        yItem.Click += new System.EventHandler(this.YMenu_Click);
-        chooseDimensionToolStripMenuItem.DropDownItems.Add(xItem);
-        chooseYDimensionToolStripMenuItem.DropDownItems.Add(yItem);
-      }
-    }
-
-    private ToolStripMenuItem MakeMenuItem(String axis, String label, int i) {
-      ToolStripMenuItem xItem = new ToolStripMenuItem();
-      xItem.Name = "obj" + i;
-      xItem.Size = new System.Drawing.Size(269, 38);
-      xItem.Text = label;
-      return xItem;
-    }
-
-    private void YMenu_Click(object sender, EventArgs e) {
-      ToolStripMenuItem item = (ToolStripMenuItem)sender;
-      yDim = Int32.Parse(item.Name.Remove(0, 3));
-      String label = item.Text;
-      this.chooseYDimensionToolStripMenuItem.Text = label;
-      this.chart.ChartAreas[0].AxisY.Title = label;
-      UpdateChart();
-    }
-
-    private void XMenu_Click(object sender, EventArgs e) {
-      ToolStripMenuItem item = (ToolStripMenuItem)sender;
-      xDim = Int32.Parse(item.Name.Remove(0, 3));
-      String label = item.Text;
-      this.chooseDimensionToolStripMenuItem.Text = label;
-      this.chart.ChartAreas[0].AxisX.Title = label;
-      UpdateChart();
-    }
-
-    private void FillSeries(double[][] qualities, double[][] solutions, Series series) {
-      series.Points.Clear();
-      if (qualities == null || qualities.Length == 0) return;
-      int jx = xDim - qualities[0].Length;
-      int jy = yDim - qualities[0].Length;
-      if ((jx >= 0 || jy >= 0) && solutions == null) {
-        return;
-      }
-      for (int i = 0; i < qualities.Length; i++) {   //Assumtion: Columnwise
-        double[] d = qualities[i];
-        double[] q = null;
-        if (jx >= 0 || jy >= 0) { q = solutions[i]; }
-        series.Points.AddXY(jx < 0 ? d[xDim] : q[jx], jy < 0 ? d[yDim] : q[jy]);
-      }
-    }
-
-    private void BuildEmptySeries() {
-
-      this.chart.Series.Add(QUALITIES);
-      qualitySeries = this.chart.Series[QUALITIES];
-
-      this.chart.Series[QUALITIES].LegendText = QUALITIES;
-      this.chart.Series[QUALITIES].ChartType = SeriesChartType.FastPoint;
-
-      this.chart.Series.Add(PARETO_FRONT);
-      paretoSeries = this.chart.Series[PARETO_FRONT];
-      paretoSeries.Color = Color.FromArgb(100, Color.Orange);
-      this.chart.Series[PARETO_FRONT].LegendText = PARETO_FRONT;
-      this.chart.Series[PARETO_FRONT].ChartType = SeriesChartType.FastPoint;
-    }
-  }
-}
-
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs	(revision 15244)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.Designer.cs	(revision 15244)
@@ -0,0 +1,129 @@
+﻿#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.Problems.TestFunctions.Views {
+  partial class ParetoFrontScatterPlotView {
+    /// <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.scatterPlotView = new HeuristicLab.Analysis.Views.ScatterPlotView();
+      this.xAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.yAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.xLabel = new System.Windows.Forms.Label();
+      this.yLabel = new System.Windows.Forms.Label();
+      this.SuspendLayout();
+      // 
+      // scatterPlotView
+      // 
+      this.scatterPlotView.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.scatterPlotView.Caption = "ScatterPlot View";
+      this.scatterPlotView.Content = null;
+      this.scatterPlotView.Location = new System.Drawing.Point(3, 37);
+      this.scatterPlotView.Name = "scatterPlotView";
+      this.scatterPlotView.ReadOnly = false;
+      this.scatterPlotView.ShowName = false;
+      this.scatterPlotView.Size = new System.Drawing.Size(615, 342);
+      this.scatterPlotView.TabIndex = 3;
+      // 
+      // xAxisComboBox
+      // 
+      this.xAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.xAxisComboBox.FormattingEnabled = true;
+      this.xAxisComboBox.Location = new System.Drawing.Point(29, 3);
+      this.xAxisComboBox.Name = "xAxisComboBox";
+      this.xAxisComboBox.Size = new System.Drawing.Size(135, 28);
+      this.xAxisComboBox.TabIndex = 4;
+      this.xAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.axisComboBox_SelectedIndexChanged);
+      // 
+      // yAxisComboBox
+      // 
+      this.yAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.yAxisComboBox.FormattingEnabled = true;
+      this.yAxisComboBox.Location = new System.Drawing.Point(240, 3);
+      this.yAxisComboBox.Name = "yAxisComboBox";
+      this.yAxisComboBox.Size = new System.Drawing.Size(135, 28);
+      this.yAxisComboBox.TabIndex = 5;
+      this.yAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.axisComboBox_SelectedIndexChanged);
+      // 
+      // xLabel
+      // 
+      this.xLabel.AutoSize = true;
+      this.xLabel.Location = new System.Drawing.Point(3, 6);
+      this.xLabel.Name = "xLabel";
+      this.xLabel.Size = new System.Drawing.Size(20, 20);
+      this.xLabel.TabIndex = 6;
+      this.xLabel.Text = "x:";
+      // 
+      // yLabel
+      // 
+      this.yLabel.AutoSize = true;
+      this.yLabel.Location = new System.Drawing.Point(214, 6);
+      this.yLabel.Name = "yLabel";
+      this.yLabel.Size = new System.Drawing.Size(20, 20);
+      this.yLabel.TabIndex = 7;
+      this.yLabel.Text = "y:";
+      // 
+      // ParetoFrontScatterPlotView
+      // 
+      this.AllowDrop = true;
+      this.Controls.Add(this.yLabel);
+      this.Controls.Add(this.xLabel);
+      this.Controls.Add(this.yAxisComboBox);
+      this.Controls.Add(this.xAxisComboBox);
+      this.Controls.Add(this.scatterPlotView);
+      this.Margin = new System.Windows.Forms.Padding(6);
+      this.Name = "ParetoFrontScatterPlotView";
+      this.Size = new System.Drawing.Size(621, 382);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+    private HeuristicLab.Analysis.Views.ScatterPlotView scatterPlotView;
+    private System.Windows.Forms.ComboBox xAxisComboBox;
+    private System.Windows.Forms.ComboBox yAxisComboBox;
+    private System.Windows.Forms.Label xLabel;
+    private System.Windows.Forms.Label yLabel;
+  }
+}
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs	(revision 15244)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/ParetoFrontScatterPlotView.cs	(revision 15244)
@@ -0,0 +1,187 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
+
+namespace HeuristicLab.Problems.TestFunctions.Views {
+  [View("Scatter Plot")]
+  [Content(typeof(ParetoFrontScatterPlot))]
+  public partial class ParetoFrontScatterPlotView : ItemView {
+
+    private readonly ScatterPlot scatterPlot;
+    private readonly ScatterPlotDataRow qualitiesRow;
+    private readonly ScatterPlotDataRow paretoFrontRow;
+
+    private int oldObjectives = -1;
+    private int oldProblemSize = -1;
+
+    private bool suppressEvents;
+
+    public new ParetoFrontScatterPlot Content {
+      get { return (ParetoFrontScatterPlot)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ParetoFrontScatterPlotView() {
+      InitializeComponent();
+
+      scatterPlot = new ScatterPlot();
+
+      qualitiesRow = new ScatterPlotDataRow("Qualities", string.Empty, Enumerable.Empty<Point2D<double>>()) {
+        VisualProperties = {
+          PointSize = 8 ,
+          PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle
+        }
+      };
+      scatterPlot.Rows.Add(qualitiesRow);
+
+      paretoFrontRow = new ScatterPlotDataRow("Best Known Pareto Front", string.Empty, Enumerable.Empty<Point2D<double>>()) {
+        VisualProperties = {
+            PointSize = 4,
+            PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Square
+          }
+      };
+      scatterPlot.Rows.Add(paretoFrontRow);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      if (Content == null) {
+        scatterPlotView.Content = null;
+        xAxisComboBox.Items.Clear();
+        xAxisComboBox.SelectedIndex = -1;
+        yAxisComboBox.Items.Clear();
+        yAxisComboBox.SelectedIndex = -1;
+        return;
+      }
+
+      scatterPlotView.Content = scatterPlot;
+
+      if (oldObjectives != Content.Objectives || oldProblemSize != Content.ProblemSize)
+        UpdateAxisComboBoxes();
+
+      UpdateChartData();
+
+      oldObjectives = Content.Objectives;
+      oldProblemSize = Content.ProblemSize;
+    }
+
+    private void UpdateChartData() {
+      if (InvokeRequired) {
+        Invoke((Action)UpdateChartData);
+        return;
+      }
+
+      int xDimGlobal = xAxisComboBox.SelectedIndex;
+      int yDimGlobal = yAxisComboBox.SelectedIndex;
+
+      qualitiesRow.Points.Replace(CreatePoints(Content.Qualities, Content.Solutions, xDimGlobal, yDimGlobal));
+
+      paretoFrontRow.Points.Replace(CreatePoints(Content.ParetoFront, null, xDimGlobal, yDimGlobal));
+      paretoFrontRow.VisualProperties.IsVisibleInLegend = paretoFrontRow.Points.Count > 0; // hide if empty
+    }
+
+    private void UpdateAxisComboBoxes() {
+      try {
+        suppressEvents = true;
+
+        string prevSelectedX = (string)xAxisComboBox.SelectedItem;
+        string prevSelectedY = (string)yAxisComboBox.SelectedItem;
+
+        xAxisComboBox.Items.Clear();
+        yAxisComboBox.Items.Clear();
+
+        // Add Objectives first
+        for (int i = 0; i < Content.Objectives; i++) {
+          xAxisComboBox.Items.Add("Objective " + i);
+          yAxisComboBox.Items.Add("Objective " + i);
+        }
+
+        // Add Problem Dimension
+        for (int i = 0; i < Content.ProblemSize; i++) {
+          xAxisComboBox.Items.Add("Problem Dimension " + i);
+          yAxisComboBox.Items.Add("Problem Dimension " + i);
+        }
+
+        // Selection
+        int count = xAxisComboBox.Items.Count;
+        if (count > 0) {
+          if (prevSelectedX != null && xAxisComboBox.Items.Contains(prevSelectedX))
+            xAxisComboBox.SelectedItem = prevSelectedX;
+          else xAxisComboBox.SelectedIndex = 0;
+
+          if (prevSelectedY != null && yAxisComboBox.Items.Contains(prevSelectedY))
+            yAxisComboBox.SelectedItem = prevSelectedY;
+          else yAxisComboBox.SelectedIndex = Math.Min(1, count - 1);
+        } else {
+          xAxisComboBox.SelectedIndex = -1;
+          yAxisComboBox.SelectedIndex = -1;
+        }
+
+        UpdateAxisDescription();
+      } finally {
+        suppressEvents = false;
+      }
+    }
+
+    private void UpdateAxisDescription() {
+      scatterPlot.VisualProperties.XAxisTitle = (string)xAxisComboBox.SelectedItem;
+      scatterPlot.VisualProperties.YAxisTitle = (string)yAxisComboBox.SelectedItem;
+    }
+
+    private static Point2D<double>[] CreatePoints(double[][] qualities, double[][] solutions, int xDimGlobal, int yDimGlobal) {
+      if (qualities == null || qualities.Length == 0) return new Point2D<double>[0];
+
+      int objectives = qualities[0].Length;
+
+      // "Global" dimension index describes the index as if the qualities and solutions would be in a single array
+      // If the global dimension index is too long for the qualities, use solutions
+      var xDimArray = xDimGlobal < objectives ? qualities : solutions;
+      var yDimArray = yDimGlobal < objectives ? qualities : solutions;
+      var xDimIndex = xDimGlobal < objectives ? xDimGlobal : xDimGlobal - objectives;
+      var yDimIndex = yDimGlobal < objectives ? yDimGlobal : yDimGlobal - objectives;
+
+      if (xDimArray == null || yDimArray == null)
+        return new Point2D<double>[0];
+
+      var points = new Point2D<double>[xDimArray.Length];
+      for (int i = 0; i < xDimArray.Length; i++) {
+        points[i] = new Point2D<double>(xDimArray[i][xDimIndex], yDimArray[i][yDimIndex]);
+      }
+      return points;
+    }
+
+    #region Event Handler
+    private void axisComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (suppressEvents) return;
+      UpdateAxisDescription();
+      UpdateChartData();
+    }
+    #endregion
+  }
+}
Index: /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame	(revision 15243)
+++ /stable/HeuristicLab.Problems.TestFunctions.Views/3.3/Plugin.cs.frame	(revision 15244)
@@ -28,4 +28,6 @@
   [Plugin("HeuristicLab.Problems.TestFunctions.Views", "3.3.14.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.TestFunctions.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Analysis.Views", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
@@ -40,5 +42,4 @@
   [PluginDependency("HeuristicLab.Problems.TestFunctions", "3.3")]
   [PluginDependency("HeuristicLab.Problems.TestFunctions.MultiObjective", "3.3")]
-  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
   public class HeuristicLabProblemsTestFunctionsViewsPlugin : PluginBase {
   }
