Index: branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 16692)
@@ -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.
@@ -52,4 +52,9 @@
     }
 
+    /// <summary>
+    /// Creates a new dataset. The variableValues are not cloned.
+    /// </summary>
+    /// <param name="variableNames">The names of the variables in the dataset</param>
+    /// <param name="variableValues">The values for the variables (column-oriented storage). Values are not cloned!</param>
     public Dataset(IEnumerable<string> variableNames, IEnumerable<IList> variableValues)
       : base() {
@@ -69,5 +74,4 @@
         throw new ArgumentException(message);
       }
-
       rows = variableValues.First().Count;
       this.variableNames = new List<string>(variableNames);
@@ -75,17 +79,5 @@
       for (int i = 0; i < this.variableNames.Count; i++) {
         var values = variableValues.ElementAt(i);
-        IList clonedValues = null;
-        if (values is IList<double>)
-          clonedValues = new List<double>(values.Cast<double>());
-        else if (values is IList<string>)
-          clonedValues = new List<string>(values.Cast<string>());
-        else if (values is IList<DateTime>)
-          clonedValues = new List<DateTime>(values.Cast<DateTime>());
-        else {
-          this.variableNames = new List<string>();
-          this.variableValues = new Dictionary<string, IList>();
-          throw new ArgumentException("The variable values must be of type IList<double>, IList<string> or IList<DateTime>");
-        }
-        this.variableValues.Add(this.variableNames[i], clonedValues);
+        this.variableValues.Add(this.variableNames[i], values);
       }
     }
@@ -116,4 +108,29 @@
         this.variableValues.Add(columName, values);
       }
+    }
+
+    public ModifiableDataset ToModifiable() {
+      var values = new List<IList>();
+      foreach (var v in variableNames) {
+        if (VariableHasType<double>(v)) {
+          values.Add(new List<double>((IList<double>)variableValues[v]));
+        } else if (VariableHasType<string>(v)) {
+          values.Add(new List<string>((IList<string>)variableValues[v]));
+        } else if (VariableHasType<DateTime>(v)) {
+          values.Add(new List<DateTime>((IList<DateTime>)variableValues[v]));
+        } else {
+          throw new ArgumentException("Unknown variable type.");
+        }
+      }
+      return new ModifiableDataset(variableNames, values);
+    }
+    /// <summary>
+    /// Shuffle a dataset's rows
+    /// </summary>
+    /// <param name="random">Random number generator used for shuffling.</param>
+    /// <returns>A shuffled copy of the current dataset.</returns>
+    public Dataset Shuffle(IRandom random) {
+      var values = variableNames.Select(x => variableValues[x]).ToList();
+      return new Dataset(variableNames, values.ShuffleLists(random));
     }
 
@@ -157,6 +174,15 @@
     }
     public IEnumerable<string> DoubleVariables {
-      get { return variableValues.Where(p => p.Value is List<double>).Select(p => p.Key); }
-    }
+      get { return variableValues.Where(p => p.Value is IList<double>).Select(p => p.Key); }
+    }
+
+    public IEnumerable<string> StringVariables {
+      get { return variableValues.Where(p => p.Value is IList<string>).Select(p => p.Key); }
+    }
+
+    public IEnumerable<string> DateTimeVariables {
+      get { return variableValues.Where(p => p.Value is IList<DateTime>).Select(p => p.Key); }
+    }
+
     public IEnumerable<double> GetDoubleValues(string variableName) {
       return GetValues<double>(variableName);
@@ -171,5 +197,5 @@
     public ReadOnlyCollection<double> GetReadOnlyDoubleValues(string variableName) {
       var values = GetValues<double>(variableName);
-      return values.AsReadOnly();
+      return new ReadOnlyCollection<double>(values);
     }
     public double GetDoubleValue(string variableName, int row) {
@@ -180,13 +206,40 @@
       return GetValues<double>(variableName, rows);
     }
+
+    public string GetStringValue(string variableName, int row) {
+      var values = GetValues<string>(variableName);
+      return values[row];
+    }
+
+    public IEnumerable<string> GetStringValues(string variableName, IEnumerable<int> rows) {
+      return GetValues<string>(variableName, rows);
+    }
+    public ReadOnlyCollection<string> GetReadOnlyStringValues(string variableName) {
+      var values = GetValues<string>(variableName);
+      return new ReadOnlyCollection<string>(values);
+    }
+
+    public DateTime GetDateTimeValue(string variableName, int row) {
+      var values = GetValues<DateTime>(variableName);
+      return values[row];
+    }
+    public IEnumerable<DateTime> GetDateTimeValues(string variableName, IEnumerable<int> rows) {
+      return GetValues<DateTime>(variableName, rows);
+    }
+    public ReadOnlyCollection<DateTime> GetReadOnlyDateTimeValues(string variableName) {
+      var values = GetValues<DateTime>(variableName);
+      return new ReadOnlyCollection<DateTime>(values);
+    }
+
+
     private IEnumerable<T> GetValues<T>(string variableName, IEnumerable<int> rows) {
       var values = GetValues<T>(variableName);
       return rows.Select(x => values[x]);
     }
-    private List<T> GetValues<T>(string variableName) {
+    private IList<T> GetValues<T>(string variableName) {
       IList list;
       if (!variableValues.TryGetValue(variableName, out list))
         throw new ArgumentException("The variable " + variableName + " does not exist in the dataset.");
-      List<T> values = list as List<T>;
+      IList<T> values = list as IList<T>;
       if (values == null) throw new ArgumentException("The variable " + variableName + " is not a " + typeof(T) + " variable.");
       return values;
@@ -201,15 +254,22 @@
     public int Rows {
       get { return rows; }
-      set { throw new NotSupportedException(); }
-    }
+    }
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { throw new NotSupportedException(); }
+    }
+
     public int Columns {
       get { return variableNames.Count; }
-      set { throw new NotSupportedException(); }
-    }
-    public bool SortableView {
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { throw new NotSupportedException(); }
+    }
+    bool IStringConvertibleMatrix.SortableView {
       get { return false; }
       set { throw new NotSupportedException(); }
     }
-    public bool ReadOnly {
+    bool IStringConvertibleMatrix.ReadOnly {
       get { return true; }
     }
@@ -222,5 +282,5 @@
       set { throw new NotSupportedException(); }
     }
-    public string GetValue(int rowIndex, int columnIndex) {
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
       return variableValues[variableNames[columnIndex]][rowIndex].ToString();
     }
