Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ChangeDataOfOptimizersMenuItem.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ChangeDataOfOptimizersMenuItem.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ChangeDataOfOptimizersMenuItem.cs	(revision 15973)
@@ -0,0 +1,115 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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 System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimizer;
+using MenuItem = HeuristicLab.MainForm.WindowsForms.MenuItem;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  internal sealed class ChangeDataOfOptimizersMenuItem : MenuItem, IOptimizerUserInterfaceItemProvider {
+    public override string Name {
+      get { return "Change problem data"; }
+    }
+    public override IEnumerable<string> Structure {
+      get { return new string[] { "&Edit", "&Data Analysis" }; }
+    }
+    public override int Position {
+      get { return 5400; }
+    }
+    public override string ToolTipText {
+      get { return "This command changes the problem data of all optimizers in the active view."; }
+    }
+
+    protected override void OnToolStripItemSet(EventArgs e) {
+      ToolStripItem.Enabled = false;
+    }
+
+    protected override void OnActiveViewChanged(object sender, EventArgs e) {
+      IContentView activeView = MainFormManager.MainForm.ActiveView as IContentView;
+      if (activeView == null) {
+        ToolStripItem.Enabled = false;
+        return;
+      }
+
+      var optimizer = activeView.Content as IOptimizer;
+      if (optimizer == null) {
+        ToolStripItem.Enabled = false;
+        return;
+      }
+
+      ToolStripItem.Enabled = true;
+    }
+
+    public override void Execute() {
+      using (OpenFileDialog openFileDialog = new OpenFileDialog()) {
+        openFileDialog.Title = "Open Problem file";
+        openFileDialog.FileName = "Item";
+        openFileDialog.Multiselect = false;
+        openFileDialog.DefaultExt = "hl";
+        openFileDialog.Filter = "HeuristicLab Files|*.hl|All Files|*.*";
+
+        if (openFileDialog.ShowDialog() != DialogResult.OK) return;
+
+        var content = ContentManager.Load(openFileDialog.FileName);
+        var problem = content as IDataAnalysisProblem;
+        IDataAnalysisProblemData problemData = null;
+        if (problem != null) {
+          problemData = problem.ProblemData;
+        } else {
+          problemData = content as IDataAnalysisProblemData;
+        }
+        if (problemData == null) throw new ArgumentException("The specified file does not contain a HeuristicLab problem.");
+
+        var activeView = (IContentView)MainFormManager.MainForm.ActiveView;
+        var optimizer = (IOptimizer)activeView.Content;
+        var newOptimizer = (IOptimizer)optimizer.Clone();
+
+        var algorithm = newOptimizer as IAlgorithm;
+        if (algorithm != null) {
+          ChangeProblemData(algorithm, problemData);
+        }
+        foreach (var alg in newOptimizer.NestedOptimizers.OfType<IAlgorithm>()) {
+          ChangeProblemData(alg, (IDataAnalysisProblemData)problemData.Clone());
+          if (problem != null) alg.Name += " " + problem.Name;
+        }
+
+        MainFormManager.MainForm.ShowContent(newOptimizer);
+      }
+
+    }
+
+    private void ChangeProblemData(IAlgorithm algorithm, IDataAnalysisProblemData problemData) {
+      if (algorithm == null) throw new ArgumentNullException("algorithm");
+      if (problemData == null) throw new ArgumentNullException("problemData");
+
+      var problem = algorithm.Problem as IDataAnalysisProblem;
+      if (problem != null) problem.ProblemDataParameter.ActualValue = problemData;
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs	(revision 15973)
@@ -2,5 +2,5 @@
 
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,9 +23,6 @@
 
 using System;
-using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
-using System.Linq.Expressions;
-using HeuristicLab.Common;
 using HeuristicLab.MainForm;
 using HeuristicLab.Optimization;
@@ -33,5 +30,4 @@
 
 using MenuItem = HeuristicLab.MainForm.WindowsForms.MenuItem;
-using ValuesType = System.Collections.Generic.Dictionary<string, System.Collections.IList>;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -79,61 +75,11 @@
       mainForm.AddOperationProgressToContent(activeView.Content, "Removing duplicate datasets.");
 
-      Action<IContentView> action = (view) => {
-        var variableValuesMapping = new Dictionary<ValuesType, ValuesType>();
-        foreach (var problemData in view.Content.GetObjectGraphObjects(excludeStaticMembers: true).OfType<IDataAnalysisProblemData>()) {
-          var dataset = problemData.Dataset as Dataset;
-          if (dataset == null) continue;
-          var originalValues = variableValuesGetter(dataset);
-          var matchingValues = GetEqualValues(originalValues, variableValuesMapping);
-          variableValuesSetter(dataset, matchingValues);
-        }
-      };
+      Action<IContentView> action = (view) => DatasetUtil.RemoveDuplicateDatasets(view.Content);
 
-      action.BeginInvoke(activeView, delegate(IAsyncResult result) {
+      action.BeginInvoke(activeView, delegate (IAsyncResult result) {
         action.EndInvoke(result);
         mainForm.RemoveOperationProgressFromContent(activeView.Content);
       }, null);
     }
-
-    private static ValuesType GetEqualValues(ValuesType originalValues, Dictionary<ValuesType, ValuesType> variableValuesMapping) {
-      if (variableValuesMapping.ContainsKey(originalValues)) return variableValuesMapping[originalValues];
-
-      var matchingValues = variableValuesMapping.FirstOrDefault(kv => kv.Key == kv.Value && EqualVariableValues(originalValues, kv.Key)).Key ?? originalValues;
-      variableValuesMapping[originalValues] = matchingValues;
-      return matchingValues;
-    }
-
-    private static bool EqualVariableValues(ValuesType values1, ValuesType values2) {
-      //compare variable names for equality
-      if (!values1.Keys.SequenceEqual(values2.Keys)) return false;
-      foreach (var key in values1.Keys) {
-        var v1 = values1[key];
-        var v2 = values2[key];
-        if (v1.Count != v2.Count) return false;
-        for (int i = 0; i < v1.Count; i++) {
-          if (!v1[i].Equals(v2[i])) return false;
-        }
-      }
-      return true;
-    }
-
-    private static readonly Action<Dataset, Dictionary<string, IList>> variableValuesSetter;
-    private static readonly Func<Dataset, Dictionary<string, IList>> variableValuesGetter;
-    /// <summary>
-    /// The static initializer is used to create expressions for getting and setting the private variableValues field in the dataset.
-    /// This is done by expressions because the field is private and compiled expression calls are much faster compared to standad reflection calls.
-    /// </summary>
-    static ShrinkDataAnalysisRunsMenuItem() {
-      var dataset = Expression.Parameter(typeof(Dataset));
-      var variableValues = Expression.Parameter(typeof(ValuesType));
-      var valuesExpression = Expression.Field(dataset, "variableValues");
-      var assignExpression = Expression.Assign(valuesExpression, variableValues);
-
-      var variableValuesSetExpression = Expression.Lambda<Action<Dataset, ValuesType>>(assignExpression, dataset, variableValues);
-      variableValuesSetter = variableValuesSetExpression.Compile();
-
-      var variableValuesGetExpression = Expression.Lambda<Func<Dataset, ValuesType>>(valuesExpression, dataset);
-      variableValuesGetter = variableValuesGetExpression.Compile();
-    }
   }
 }
