Index: branches/2904_CalculateImpacts/3.4/Dataset.cs
===================================================================
--- branches/2904_CalculateImpacts/3.4/Dataset.cs	(revision 15808)
+++ branches/2904_CalculateImpacts/3.4/Dataset.cs	(revision 16188)
@@ -38,8 +38,10 @@
     protected Dataset(Dataset original, Cloner cloner)
       : base(original, cloner) {
+      // no need to clone the variable values because these can't be modified
       variableValues = new Dictionary<string, IList>(original.variableValues);
       variableNames = new List<string>(original.variableNames);
       rows = original.rows;
     }
+
     public override IDeepCloneable Clone(Cloner cloner) { return new Dataset(this, cloner); }
 
@@ -58,32 +60,29 @@
     /// <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() {
+      : this(variableNames, variableValues, cloneValues: true) {
+    }
+
+    protected Dataset(IEnumerable<string> variableNames, IEnumerable<IList> variableValues, bool cloneValues = false) {
       Name = "-";
-      if (!variableNames.Any()) {
+
+      if (variableNames.Any()) {
+        this.variableNames = new List<string>(variableNames);
+      } else {
         this.variableNames = Enumerable.Range(0, variableValues.Count()).Select(x => "Column " + x).ToList();
-      } else if (variableNames.Count() != variableValues.Count()) {
-        throw new ArgumentException("Number of variable names doesn't match the number of columns of variableValues");
-      } else if (!variableValues.All(list => list.Count == variableValues.First().Count)) {
-        throw new ArgumentException("The number of values must be equal for every variable");
-      } else if (variableNames.Distinct().Count() != variableNames.Count()) {
-        var duplicateVariableNames =
-          variableNames.GroupBy(v => v).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
-        string message = "The dataset cannot contain duplicate variables names: " + Environment.NewLine;
-        foreach (var duplicateVariableName in duplicateVariableNames)
-          message += duplicateVariableName + Environment.NewLine;
-        throw new ArgumentException(message);
-      }
+      }
+      // check if the arguments are consistent (no duplicate variables, same number of rows, correct data types, ...)
+      CheckArguments(this.variableNames, variableValues);
+
       rows = variableValues.First().Count;
-      this.variableNames = new List<string>(variableNames);
-      this.variableValues = new Dictionary<string, IList>(this.variableNames.Count);
-      for (int i = 0; i < this.variableNames.Count; i++) {
-        var variableName = this.variableNames[i];
-        var values = variableValues.ElementAt(i);
-
-        if (!IsAllowedType(values)) {
-          throw new ArgumentException(string.Format("Unsupported type {0} for variable {1}.", GetElementType(values), variableName));
+
+      if (cloneValues) {
+        this.variableValues = CloneValues(this.variableNames, variableValues);
+      } else {
+        this.variableValues = new Dictionary<string, IList>(this.variableNames.Count);
+        for (int i = 0; i < this.variableNames.Count; i++) {
+          var variableName = this.variableNames[i];
+          var values = variableValues.ElementAt(i);
+          this.variableValues.Add(variableName, values);
         }
-
-        this.variableValues.Add(variableName, values);
       }
     }
@@ -117,17 +116,5 @@
 
     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);
+      return new ModifiableDataset(variableNames, variableNames.Select(v => variableValues[v]), true);
     }
 
@@ -142,5 +129,5 @@
     }
 
-    protected Dataset(Dataset dataset) : this(dataset.variableNames, dataset.variableValues.Values) { }
+
 
     #region Backwards compatible code, remove with 3.5
@@ -238,6 +225,4 @@
       return new ReadOnlyCollection<DateTime>(values);
     }
-
-
     private IEnumerable<T> GetValues<T>(string variableName, IEnumerable<int> rows) {
       var values = GetValues<T>(variableName);
@@ -255,5 +240,4 @@
       return variableValues[variableName] is IList<T>;
     }
-
     protected Type GetVariableType(string variableName) {
       IList list;
@@ -263,24 +247,67 @@
       return GetElementType(list);
     }
-
-    protected Type GetElementType(IList list) {
+    protected static Type GetElementType(IList list) {
       var type = list.GetType();
       return type.IsGenericType ? type.GetGenericArguments()[0] : type.GetElementType();
     }
-
-    protected bool IsAllowedType(IList list) {
+    protected static bool IsAllowedType(IList list) {
       var type = GetElementType(list);
       return IsAllowedType(type);
     }
-
-    protected bool IsAllowedType(Type type) {
+    protected static bool IsAllowedType(Type type) {
       return type == typeof(double) || type == typeof(string) || type == typeof(DateTime);
+    }
+
+    protected static void CheckArguments(IEnumerable<string> variableNames, IEnumerable<IList> variableValues) {
+      if (variableNames.Count() != variableValues.Count()) {
+        throw new ArgumentException("Number of variable names doesn't match the number of columns of variableValues");
+      } else if (!variableValues.All(list => list.Count == variableValues.First().Count)) {
+        throw new ArgumentException("The number of values must be equal for every variable");
+      } else if (variableNames.Distinct().Count() != variableNames.Count()) {
+        var duplicateVariableNames =
+          variableNames.GroupBy(v => v).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
+        string message = "The dataset cannot contain duplicate variables names: " + Environment.NewLine;
+        foreach (var duplicateVariableName in duplicateVariableNames)
+          message += duplicateVariableName + Environment.NewLine;
+        throw new ArgumentException(message);
+      }
+      // check if all the variables are supported
+      foreach (var t in variableNames.Zip(variableValues, Tuple.Create)) {
+        var variableName = t.Item1;
+        var values = t.Item2;
+
+        if (!IsAllowedType(values)) {
+          throw new ArgumentException(string.Format("Unsupported type {0} for variable {1}.", GetElementType(values), variableName));
+        }
+      }
+    }
+
+    protected static Dictionary<string, IList> CloneValues(Dictionary<string, IList> variableValues) {
+      return variableValues.ToDictionary(x => x.Key, x => CloneValues(x.Value));
+    }
+
+    protected static Dictionary<string, IList> CloneValues(IEnumerable<string> variableNames, IEnumerable<IList> variableValues) {
+      return variableNames.Zip(variableValues, Tuple.Create).ToDictionary(x => x.Item1, x => CloneValues(x.Item2));
+    }
+
+    protected static IList CloneValues(IList values) {
+      var doubleValues = values as IList<double>;
+      if (doubleValues != null) return new List<double>(doubleValues);
+
+      var stringValues = values as IList<string>;
+      if (stringValues != null) return new List<string>(stringValues);
+
+      var dateTimeValues = values as IList<DateTime>;
+      if (dateTimeValues != null) return new List<DateTime>(dateTimeValues);
+
+      throw new ArgumentException(string.Format("Unsupported variable type {0}.", GetElementType(values)));
     }
 
     #region IStringConvertibleMatrix Members
     [Storable]
-    protected int rows;
+    private int rows;
     public int Rows {
       get { return rows; }
+      protected set { rows = value; }
     }
     int IStringConvertibleMatrix.Rows {
