Index: /branches/2993_UserDefinedEvaluators/2993_UserDefinedEvaluators.sln
===================================================================
--- /branches/2993_UserDefinedEvaluators/2993_UserDefinedEvaluators.sln	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/2993_UserDefinedEvaluators.sln	(revision 16687)
@@ -0,0 +1,37 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.438
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval", "HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval\HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval.csproj", "{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Debug|x64.Build.0 = Debug|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Debug|x86.Build.0 = Debug|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Release|x64.ActiveCfg = Release|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Release|x64.Build.0 = Release|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Release|x86.ActiveCfg = Release|Any CPU
+		{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {EA8C7CA2-6128-4D1E-A5EB-E93F290CFBFE}
+	EndGlobalSection
+EndGlobal
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval.csproj
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval.csproj	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval.csproj	(revision 16687)
@@ -0,0 +1,125 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" 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>{5746863F-EFD5-4AF8-A265-C27B7F7C4C20}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Google.Protobuf, Version=3.6.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="HEAL.Attic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\packages\HEAL.Attic.1.0.0-pre04\lib\net461\HEAL.Attic.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Drawing.Common, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Drawing.Common.4.5.1\lib\net461\System.Drawing.Common.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator.cs" />
+    <Compile Include="SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator.cs" />
+    <Compile Include="SymbolicRegressionMultiObjectiveUserDefinedEvaluator.cs" />
+    <Compile Include="SymbolicRegressionSingleObjectiveUserDefinedEvaluator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/Plugin.cs
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/Plugin.cs	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/Plugin.cs	(revision 16687)
@@ -0,0 +1,20 @@
+﻿using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefined", "Provides user-defined evaluators to HeuristicLab", "3.4.0.0")]
+  [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding", "3.4")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
+  public class Plugin : PluginBase {
+  }
+}
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/Properties/AssemblyInfo.cs
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/Properties/AssemblyInfo.cs	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/Properties/AssemblyInfo.cs	(revision 16687)
@@ -0,0 +1,33 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2019 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("4026dfa4-db2e-48db-a166-43767cb61261")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.0.0")]
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator.cs
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator.cs	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator.cs	(revision 16687)
@@ -0,0 +1,68 @@
+﻿using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("User-defined Multi-objective Evaluator", "A multi-objective evaluator that aggregates the output of its evaluator collection.")]
+  [StorableType("779F7C15-63E0-4407-A28D-F4DCB1AA8267")]
+  public class SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator<T> : SymbolicDataAnalysisMultiObjectiveEvaluator<T> where T : class, IDataAnalysisProblemData {
+    private const string EvaluatorsParameterName = "Evaluators";
+    private const string MaximizationParameterName = "Maximization";
+
+    public IFixedValueParameter<ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>> EvaluatorsParameter {
+      get { return (IFixedValueParameter<ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>>)Parameters[EvaluatorsParameterName]; }
+    }
+
+    public ILookupParameter<BoolArray> MaximizationParameter {
+      get { return (ILookupParameter<BoolArray>)Parameters[MaximizationParameterName]; }
+    }
+
+    public ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>> Evaluators {
+      get { return EvaluatorsParameter.Value; }
+    }
+
+    public override IEnumerable<bool> Maximization => Evaluators.Select(x => x.Maximization);
+
+    public SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator() {
+      Parameters.Add(new FixedValueParameter<ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>>(EvaluatorsParameterName, new ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>()));
+      Parameters.Add(new LookupParameter<BoolArray>(MaximizationParameterName));
+    }
+
+    public SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator(SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator<T> original, Cloner cloner) : base(original, cloner) { }
+
+    [StorableConstructor]
+    protected SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator(StorableConstructorFlag deserializing) : base(deserializing) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator<T>(this, cloner);
+    }
+
+    public override double[] Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, T problemData, IEnumerable<int> rows) {
+      var evaluators = Evaluators;
+      var qualities = new double[evaluators.Count];
+      for (int i = 0; i < qualities.Length; ++i) {
+        qualities[i] = evaluators[i].Evaluate(context, tree, problemData, rows);
+      }
+      QualitiesParameter.ActualValue = new DoubleArray(qualities);
+      return qualities;
+    }
+
+    public override IOperation InstrumentedApply() {
+      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+
+      if (MaximizationParameter.ActualValue.Length != Evaluators.Count) {
+        MaximizationParameter.ActualValue = new BoolArray(Maximization.ToArray());
+      }
+
+      var qualities = Evaluate(ExecutionContext, solution, problemData, problemData.TrainingIndices);
+      QualitiesParameter.ActualValue = new DoubleArray(qualities);
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator.cs
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator.cs	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator.cs	(revision 16687)
@@ -0,0 +1,86 @@
+﻿using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("User-defined Single-objective Evaluator", "A single-objective evaluator that aggregates the output of its evaluator collection.")]
+  [StorableType("1E668115-AF2A-4037-8E3C-7B279EC72770")]
+  public class SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator<T> : SymbolicDataAnalysisSingleObjectiveEvaluator<T> where T : class, IDataAnalysisProblemData {
+    private const string EvaluatorsParameterName = "Evaluators";
+    private const string MaximizationParameterName = "Maximization";
+    private const string ObjectiveWeightsParameterName = "Weights";
+
+    public IValueParameter<DoubleArray> ObjectiveWeightsParameter {
+      get { return (IValueParameter<DoubleArray>)Parameters[ObjectiveWeightsParameterName]; }
+    }
+
+    public IFixedValueParameter<ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>> EvaluatorsParameter {
+      get { return (IFixedValueParameter<ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>>)Parameters[EvaluatorsParameterName]; }
+    }
+
+    public IFixedValueParameter<BoolValue> MaximizationParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+    }
+
+    public ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>> Evaluators {
+      get { return EvaluatorsParameter.Value; }
+    }
+
+    public DoubleArray ObjectiveWeights => ObjectiveWeightsParameter.Value;
+
+    public override bool Maximization => false;
+
+    public SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator() : base() {
+      Parameters.Add(new FixedValueParameter<ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>>(EvaluatorsParameterName, new ItemList<ISymbolicDataAnalysisSingleObjectiveEvaluator<T>>()));
+      Parameters.Add(new FixedValueParameter<BoolValue>(MaximizationParameterName, new BoolValue(false)));
+      Parameters.Add(new ValueParameter<DoubleArray>(ObjectiveWeightsParameterName, new DoubleArray()));
+    }
+
+    public SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator(SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator<T> original, Cloner cloner) : base(original, cloner) { }
+
+    [StorableConstructor]
+    protected SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator(StorableConstructorFlag deserializing) : base(deserializing) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator<T>(this, cloner);
+    }
+
+    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, T problemData, IEnumerable<int> rows) {
+      var weights = ObjectiveWeights;
+
+      double eval(ISymbolicDataAnalysisSingleObjectiveEvaluator<T> e) {
+        var q = e.Evaluate(context, tree, problemData, rows);
+        return e.Maximization ? -q : q;
+      }
+
+      var quality = 0d;
+      for (int i = 0; i < weights.Length; ++i) {
+        quality += weights[i] * eval(Evaluators[i]);
+      }
+
+      if (double.IsNaN(quality) || double.IsInfinity(quality)) {
+        quality = double.MaxValue;
+      }
+
+      if (DecimalPlaces >= 0) {
+        quality = Math.Round(quality, DecimalPlaces);
+      }
+
+      return quality;
+    }
+
+    public override IOperation InstrumentedApply() {
+      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+
+      var quality = Evaluate(ExecutionContext, solution, problemData, problemData.TrainingIndices);
+      QualityParameter.ActualValue = new DoubleValue(quality);
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicRegressionMultiObjectiveUserDefinedEvaluator.cs
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicRegressionMultiObjectiveUserDefinedEvaluator.cs	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicRegressionMultiObjectiveUserDefinedEvaluator.cs	(revision 16687)
@@ -0,0 +1,55 @@
+﻿using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [Item("Symbolic regression multi-objective user-defined evaluator", "Encapsulates a collection of single-objective evaluators and returns an array of qualities.")]
+  [StorableType("9F77E2DA-B358-47FA-9DFF-EF04C9A7769A")]
+  public class SymbolicRegressionMultiObjectiveUserDefinedEvaluator : SymbolicDataAnalysisMultiObjectiveUserDefinedEvaluator<IRegressionProblemData>, ISymbolicRegressionMultiObjectiveEvaluator {
+    private const string OptimizeConstantsParameterName = "OptimizeConstants";
+    private const string ConstantOptimizationIterationsParameterName = "ConstantOptimizationIterations";
+
+    public IFixedValueParameter<BoolValue> OptimizeConstantsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[OptimizeConstantsParameterName]; }
+    }
+
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
+    }
+
+    public bool OptimizeConstants => OptimizeConstantsParameter.Value.Value;
+
+    public int ConstantOptimizationIterations => ConstantOptimizationIterationsParameter.Value.Value;
+
+    public SymbolicRegressionMultiObjectiveUserDefinedEvaluator() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeConstantsParameterName, new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, new IntValue(10)));
+    }
+
+    protected SymbolicRegressionMultiObjectiveUserDefinedEvaluator(SymbolicRegressionMultiObjectiveUserDefinedEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicRegressionMultiObjectiveUserDefinedEvaluator(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected SymbolicRegressionMultiObjectiveUserDefinedEvaluator(StorableConstructorFlag _) : base(_) { }
+
+    public override IOperation InstrumentedApply() {
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+
+      if (OptimizeConstants) {
+        var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+        var estimationLimits = EstimationLimitsParameter.ActualValue;
+        var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+        var iterations = ConstantOptimizationIterations;
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, problemData.TrainingIndices, applyLinearScaling, iterations, true, estimationLimits.Lower, estimationLimits.Upper, true);
+      }
+
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicRegressionSingleObjectiveUserDefinedEvaluator.cs
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicRegressionSingleObjectiveUserDefinedEvaluator.cs	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/SymbolicRegressionSingleObjectiveUserDefinedEvaluator.cs	(revision 16687)
@@ -0,0 +1,58 @@
+﻿using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("Symbolic regression single-objective user-defined evaluator", "Encapsulates a collection of single-objective evaluators and aggregates their output.")]
+  [StorableType("BCA2D407-576B-4529-8586-A4DFCE117F4C")]
+  public class SymbolicRegressionSingleObjectiveUserDefinedEvaluator : SymbolicDataAnalysisSingleObjectiveUserDefinedEvaluator<IRegressionProblemData>, ISymbolicRegressionSingleObjectiveEvaluator {
+    private const string OptimizeConstantsParameterName = "OptimizeConstants";
+    private const string ConstantOptimizationIterationsParameterName = "ConstantOptimizationIterations";
+
+    public IFixedValueParameter<BoolValue> OptimizeConstantsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[OptimizeConstantsParameterName]; }
+    }
+
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
+    }
+
+    public bool OptimizeConstants => OptimizeConstantsParameter.Value.Value;
+
+    public int ConstantOptimizationIterations => ConstantOptimizationIterationsParameter.Value.Value;
+
+    public ILookupParameter<DoubleArray> QualitiesParameter => throw new System.NotImplementedException();
+
+    public SymbolicRegressionSingleObjectiveUserDefinedEvaluator() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeConstantsParameterName, new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, new IntValue(10)));
+    }
+
+    protected SymbolicRegressionSingleObjectiveUserDefinedEvaluator(SymbolicRegressionSingleObjectiveUserDefinedEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicRegressionSingleObjectiveUserDefinedEvaluator(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected SymbolicRegressionSingleObjectiveUserDefinedEvaluator(StorableConstructorFlag _) : base(_) { }
+
+    public override IOperation InstrumentedApply() {
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+
+      if (OptimizeConstants) {
+        var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+        var estimationLimits = EstimationLimitsParameter.ActualValue;
+        var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+        var iterations = ConstantOptimizationIterations;
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, problemData.TrainingIndices, applyLinearScaling, iterations, true, estimationLimits.Lower, estimationLimits.Upper, true);
+      }
+
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/packages.config
===================================================================
--- /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/packages.config	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/HeuristicLab.Problems.DataAnalysis.Symbolic.UserDefinedEval/packages.config	(revision 16687)
@@ -0,0 +1,6 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Google.Protobuf" version="3.6.1" targetFramework="net461" />
+  <package id="HEAL.Attic" version="1.0.0-pre04" targetFramework="net461" />
+  <package id="System.Drawing.Common" version="4.5.1" targetFramework="net461" />
+</packages>
Index: /branches/2993_UserDefinedEvaluators/PreBuildEvent.cmd
===================================================================
--- /branches/2993_UserDefinedEvaluators/PreBuildEvent.cmd	(revision 16687)
+++ /branches/2993_UserDefinedEvaluators/PreBuildEvent.cmd	(revision 16687)
@@ -0,0 +1,11 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+GOTO Done
+
+:Error_Handling
+ECHO There was an error while running subwcrev. Please verify that the *.cs.frame files have been correctly converted to *.cs files, otherwise HeuristicLab won't build. 
+exit 0
+
+:Done
