Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolArray.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolArray.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolArray.cs	(revision 9274)
@@ -0,0 +1,86 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("BoolArray", "Represents an array of boolean values.")]
+  [StorableClass]
+  public class BoolArray : ValueTypeArray<bool>, IStringConvertibleArray {
+    [StorableConstructor]
+    protected BoolArray(bool deserializing) : base(deserializing) { }
+    protected BoolArray(BoolArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public BoolArray() : base() { }
+    public BoolArray(int length) : base(length) { }
+    public BoolArray(bool[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BoolArray(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      bool val;
+      bool valid = bool.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetBoolFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int index) {
+      return this[index].ToString();
+    }
+    protected virtual bool SetValue(string value, int index) {
+      bool val;
+      if (bool.TryParse(value, out val)) {
+        this[index] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleArray Members
+    int IStringConvertibleArray.Length {
+      get { return Length; }
+      set { Length = value; }
+    }
+    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleArray.GetValue(int index) {
+      return GetValue(index);
+    }
+    bool IStringConvertibleArray.SetValue(string value, int index) {
+      return SetValue(value, index);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolMatrix.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolMatrix.cs	(revision 9274)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("BoolMatrix", "Represents a matrix of boolean values.")]
+  [StorableClass]
+  public class BoolMatrix : ValueTypeMatrix<bool>, IStringConvertibleMatrix {
+    [StorableConstructor]
+    protected BoolMatrix(bool deserializing) : base(deserializing) { }
+    protected BoolMatrix(BoolMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public BoolMatrix() : base() { }
+    public BoolMatrix(int rows, int columns) : base(rows, columns) { }
+    public BoolMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public BoolMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
+    public BoolMatrix(bool[,] elements) : base(elements) { }
+    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
+    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BoolMatrix(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      bool val;
+      bool valid = bool.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetBoolFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString();
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      bool val;
+      if (bool.TryParse(value, out val)) {
+        this[rowIndex, columnIndex] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/BoolValue.cs	(revision 9274)
@@ -0,0 +1,99 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("BoolValue", "Represents a boolean value.")]
+  [StorableClass]
+  public class BoolValue : ValueTypeValue<bool>, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    protected BoolValue(BoolValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public BoolValue() : base() { }
+    [StorableConstructor]
+    public BoolValue(bool value)
+      : base(value) {
+      //mkommend: Be aware that the base call refers to the storable ctor => the value is set explicitly in the ctor body.
+      //          This should not affect the persistence, because first the ctor is called and afterwards the values are set by reflection.
+      this.value = value;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BoolValue(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      BoolValue other = obj as BoolValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      bool val;
+      bool valid = bool.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetBoolFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString();
+    }
+    protected virtual bool SetValue(string value) {
+      bool val;
+      if (bool.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Comparison.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Comparison.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Comparison.cs	(revision 9274)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("Comparison", "Represents a comparison.")]
+  [StorableClass]
+  public class Comparison : ValueTypeValue<ComparisonType>, IComparable {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Enum; }
+    }
+
+    [StorableConstructor]
+    protected Comparison(bool deserializing) : base(deserializing) { }
+    protected Comparison(Comparison original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public Comparison() : base() { }
+    public Comparison(ComparisonType value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Comparison(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      Comparison other = obj as Comparison;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ComparisonType.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ComparisonType.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ComparisonType.cs	(revision 9274)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Data {
+  public enum ComparisonType {
+    Less,
+    LessOrEqual,
+    Equal,
+    GreaterOrEqual,
+    Greater,
+    NotEqual
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DateTimeValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DateTimeValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DateTimeValue.cs	(revision 9274)
@@ -0,0 +1,86 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DateTimeValue", "Represents a date and time value.")]
+  [StorableClass]
+  public class DateTimeValue : ValueTypeValue<DateTime>, IComparable, IStringConvertibleValue {
+    [StorableConstructor]
+    protected DateTimeValue(bool deserializing) : base(deserializing) { }
+    protected DateTimeValue(DateTimeValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DateTimeValue() : base() { }
+    public DateTimeValue(DateTime value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DateTimeValue(this, cloner);
+    }
+
+    public override string ToString() {
+      return Value.ToString("o");  // round-trip format
+    }
+
+    public virtual int CompareTo(object obj) {
+      DateTimeValue other = obj as DateTimeValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      DateTime val;
+      bool valid = DateTime.TryParse(value, out val);
+      errorMessage = valid ? string.Empty : "Invalid Value (values must be formatted according to the current culture settings)";
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString("o");  // round-trip format
+    }
+    protected virtual bool SetValue(string value) {
+      DateTime val;
+      if (DateTime.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleArray.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleArray.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleArray.cs	(revision 9274)
@@ -0,0 +1,86 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DoubleArray", "Represents an array of double values.")]
+  [StorableClass]
+  public class DoubleArray : ValueTypeArray<double>, IStringConvertibleArray {
+    [StorableConstructor]
+    protected DoubleArray(bool deserializing) : base(deserializing) { }
+    protected DoubleArray(DoubleArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DoubleArray() : base() { }
+    public DoubleArray(int length) : base(length) { }
+    public DoubleArray(double[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleArray(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int index) {
+      return this[index].ToString();
+    }
+    protected virtual bool SetValue(string value, int index) {
+      double val;
+      if (double.TryParse(value, out val)) {
+        this[index] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleArray Members
+    int IStringConvertibleArray.Length {
+      get { return Length; }
+      set { Length = value; }
+    }
+    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleArray.GetValue(int index) {
+      return GetValue(index);
+    }
+    bool IStringConvertibleArray.SetValue(string value, int index) {
+      return SetValue(value, index);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleMatrix.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleMatrix.cs	(revision 9274)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DoubleMatrix", "Represents a matrix of double values.")]
+  [StorableClass]
+  public class DoubleMatrix : ValueTypeMatrix<double>, IStringConvertibleMatrix {
+    [StorableConstructor]
+    protected DoubleMatrix(bool deserializing) : base(deserializing) { }
+    protected DoubleMatrix(DoubleMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DoubleMatrix() : base() { }
+    public DoubleMatrix(int rows, int columns) : base(rows, columns) { }
+    public DoubleMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public DoubleMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
+    public DoubleMatrix(double[,] elements) : base(elements) { }
+    public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
+    public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleMatrix(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString();
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      double val;
+      if (double.TryParse(value, out val)) {
+        this[rowIndex, columnIndex] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleRange.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleRange.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleRange.cs	(revision 9274)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [StorableClass]
+  [Item("DoubleRange", "Represents a range of values betweent start and end.")]
+  public class DoubleRange : StringConvertibleValueTuple<DoubleValue, DoubleValue> {
+
+    public double Start {
+      get { return Item1.Value; }
+      set { Item1.Value = value; }
+    }
+    public double End {
+      get { return Item2.Value; }
+      set { Item2.Value = value; }
+    }
+    public double Size {
+      get { return End - Start; }
+    }
+
+    [StorableConstructor]
+    protected DoubleRange(bool deserializing) : base(deserializing) { }
+    protected DoubleRange(DoubleRange original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleRange(this, cloner);
+    }
+
+    public DoubleRange() : base(new DoubleValue(), new DoubleValue()) { }
+    public DoubleRange(DoubleValue start, DoubleValue end) : base(start, end) { }
+    public DoubleRange(double start, double end) : base(new DoubleValue(start), new DoubleValue(end)) { }
+
+    public override string ToString() {
+      return string.Format("Start: {0}, End: {1}", Start, End);
+    }
+
+    public override StringConvertibleValueTuple<DoubleValue, DoubleValue> AsReadOnly() {
+      var readOnly = new DoubleRange();
+      readOnly.values = Tuple.Create<DoubleValue, DoubleValue>((DoubleValue)Item1.AsReadOnly(), (DoubleValue)Item2.AsReadOnly());
+      readOnly.readOnly = true;
+      return readOnly;
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/DoubleValue.cs	(revision 9274)
@@ -0,0 +1,99 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DoubleValue", "Represents a double value.")]
+  [StorableClass]
+  public class DoubleValue : ValueTypeValue<double>, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    [StorableConstructor]
+    protected DoubleValue(bool deserializing) : base(deserializing) { }
+    protected DoubleValue(DoubleValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DoubleValue() : base() { }
+    public DoubleValue(double value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleValue(this, cloner);
+    }
+
+    public override string ToString() {
+      return Value.ToString("r");  // round-trip format
+    }
+
+    public virtual int CompareTo(object obj) {
+      DoubleValue other = obj as DoubleValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString("r");  // round-trip format
+    }
+    protected virtual bool SetValue(string value) {
+      double val;
+      if (double.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/FormatPatterns.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/FormatPatterns.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/FormatPatterns.cs	(revision 9274)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Globalization;
+using System.Text;
+
+namespace HeuristicLab.Data {
+  public static class FormatPatterns {
+    public static string GetBoolFormatPattern() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append(bool.TrueString).Append(" | ").Append(bool.FalseString);
+      return sb.ToString();
+    }
+    public static string GetDoubleFormatPattern() {
+      StringBuilder sb = new StringBuilder();
+      NumberFormatInfo nf = CultureInfo.CurrentCulture.NumberFormat;
+      sb.Append(nf.PositiveInfinitySymbol).Append(" | ");
+      sb.Append(nf.NegativeInfinitySymbol).Append(" | ");
+      sb.Append(nf.NaNSymbol).Append(" | ");
+      sb.Append("[").Append(nf.PositiveSign).Append(" | ").Append(nf.NegativeSign).Append("]");
+      sb.Append("digits[").Append(nf.NumberDecimalSeparator).Append("[digits]]");
+      sb.Append("[(e | E)");
+      sb.Append("[").Append(nf.PositiveSign).Append(" | ").Append(nf.NegativeSign).Append("]");
+      sb.Append("digits]");
+      return sb.ToString();
+    }
+    public static string GetIntFormatPattern() {
+      StringBuilder sb = new StringBuilder();
+      NumberFormatInfo nf = CultureInfo.CurrentCulture.NumberFormat;
+      sb.Append("[").Append(nf.PositiveSign).Append(" | ").Append(nf.NegativeSign).Append("]");
+      sb.Append("digits");
+      return sb.ToString();
+    }
+    public static string GetTimeSpanFormatPattern() {
+      return "[-](d | d.hh:mm[:ss[.ff]] | hh:mm[:ss[.ff]])";
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj	(revision 9274)
@@ -0,0 +1,228 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Data</RootNamespace>
+    <AssemblyName>HeuristicLab.Data-3.3</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <IsWebBootstrapper>true</IsWebBootstrapper>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <PublishUrl>http://localhost/HeuristicLab.Data/</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Web</InstallFrom>
+    <UpdateEnabled>true</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </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>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </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>
+    <DocumentationFile>
+    </DocumentationFile>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <CodeAnalysisRuleSet>AllRules.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>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="BoolArray.cs" />
+    <Compile Include="BoolMatrix.cs" />
+    <Compile Include="BoolValue.cs" />
+    <Compile Include="Comparison.cs" />
+    <Compile Include="ComparisonType.cs" />
+    <Compile Include="PercentMatrix.cs" />
+    <Compile Include="PercentArray.cs" />
+    <Compile Include="DoubleRange.cs" />
+    <Compile Include="IntRange.cs" />
+    <Compile Include="Interfaces\IStringConvertibleValueTuple.cs" />
+    <Compile Include="PercentValue.cs" />
+    <Compile Include="DateTimeValue.cs" />
+    <Compile Include="DoubleArray.cs" />
+    <Compile Include="DoubleMatrix.cs" />
+    <Compile Include="DoubleValue.cs" />
+    <Compile Include="FormatPatterns.cs" />
+    <Compile Include="IntArray.cs" />
+    <Compile Include="IntMatrix.cs" />
+    <Compile Include="IntValue.cs" />
+    <Compile Include="Interfaces\IStringConvertibleArray.cs" />
+    <Compile Include="Interfaces\IStringConvertibleMatrix.cs" />
+    <Compile Include="Interfaces\IStringConvertibleValue.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="StringArray.cs" />
+    <Compile Include="StringMatrix.cs" />
+    <Compile Include="StringValue.cs" />
+    <Compile Include="TimeSpanValue.cs" />
+    <Compile Include="ValueTypeArray.cs" />
+    <Compile Include="ValueTypeMatrix.cs" />
+    <Compile Include="StringConvertibleValueTuple.cs" />
+    <Compile Include="ValueTypeValue.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <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>
+      <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.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>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- 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>
+  -->
+  <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>
+</Project>
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntArray.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntArray.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntArray.cs	(revision 9274)
@@ -0,0 +1,86 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("IntArray", "Represents an array of integer values.")]
+  [StorableClass]
+  public class IntArray : ValueTypeArray<int>, IStringConvertibleArray {
+    [StorableConstructor]
+    protected IntArray(bool deserializing) : base(deserializing) { }
+    protected IntArray(IntArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public IntArray() : base() { }
+    public IntArray(int length) : base(length) { }
+    public IntArray(int[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntArray(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      int val;
+      bool valid = int.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetIntFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int index) {
+      return this[index].ToString();
+    }
+    protected virtual bool SetValue(string value, int index) {
+      int val;
+      if (int.TryParse(value, out val)) {
+        this[index] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleArray Members
+    int IStringConvertibleArray.Length {
+      get { return Length; }
+      set { Length = value; }
+    }
+    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleArray.GetValue(int index) {
+      return GetValue(index);
+    }
+    bool IStringConvertibleArray.SetValue(string value, int index) {
+      return SetValue(value, index);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntMatrix.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntMatrix.cs	(revision 9274)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("IntMatrix", "Represents a matrix of integer values.")]
+  [StorableClass]
+  public class IntMatrix : ValueTypeMatrix<int>, IStringConvertibleMatrix {
+    [StorableConstructor]
+    protected IntMatrix(bool deserializing) : base(deserializing) { }
+    protected IntMatrix(IntMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public IntMatrix() : base() { }
+    public IntMatrix(int rows, int columns) : base(rows, columns) { }
+    public IntMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public IntMatrix(int rows, int columns, IEnumerable<string> columnNames,IEnumerable<string> rowNames) : base(rows, columns, columnNames,rowNames) { }
+    public IntMatrix(int[,] elements) : base(elements) { }
+    public IntMatrix(int[,] elements, IEnumerable<string> columnNames) : base(elements,columnNames) { }
+    public IntMatrix(int[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements,columnNames,rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntMatrix(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      int val;
+      bool valid = int.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetIntFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString();
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      int val;
+      if (int.TryParse(value, out val)) {
+        this[rowIndex, columnIndex] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntRange.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntRange.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntRange.cs	(revision 9274)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [StorableClass]
+  [Item("IntRange", "Represents a range of values betweent start and end.")]
+  public class IntRange : StringConvertibleValueTuple<IntValue, IntValue> {
+
+    public int Start {
+      get { return Item1.Value; }
+      set { Item1.Value = value; }
+    }
+    public int End {
+      get { return Item2.Value; }
+      set { Item2.Value = value; }
+    }
+    public int Size {
+      get { return End - Start; }
+    }
+
+    [StorableConstructor]
+    protected IntRange(bool deserializing) : base(deserializing) { }
+    protected IntRange(IntRange original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntRange(this, cloner);
+    }
+
+    public IntRange() : base(new IntValue(), new IntValue()) { }
+    public IntRange(IntValue start, IntValue end) : base(start, end) { }
+    public IntRange(int start, int end) : base(new IntValue(start), new IntValue(end)) { }
+
+    public override string ToString() {
+      return string.Format("Start: {0}, End: {1}", Start, End);
+    }
+
+    public override StringConvertibleValueTuple<IntValue, IntValue> AsReadOnly() {
+      var readOnly = new IntRange();
+      readOnly.values = Tuple.Create<IntValue, IntValue>((IntValue)Item1.AsReadOnly(), (IntValue)Item2.AsReadOnly());
+      readOnly.readOnly = true;
+      return readOnly;
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/IntValue.cs	(revision 9274)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("IntValue", "Represents an integer value.")]
+  [StorableClass]
+  public class IntValue : ValueTypeValue<int>, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    [StorableConstructor]
+    protected IntValue(bool deserializing) : base(deserializing) { }
+    protected IntValue(IntValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public IntValue() : base() { }
+    public IntValue(int value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntValue(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      IntValue other = obj as IntValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      int val;
+      bool valid = int.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetIntFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString();
+    }
+    protected virtual bool SetValue(string value) {
+      int val;
+      if (int.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleArray.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleArray.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleArray.cs	(revision 9274)
@@ -0,0 +1,38 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+
+namespace HeuristicLab.Data {
+  public interface IStringConvertibleArray : IContent {
+    int Length { get; set; }
+
+    bool ReadOnly { get; }
+
+    bool Validate(string value, out string errorMessage);
+    string GetValue(int index);
+    bool SetValue(string value, int index);
+
+    event EventHandler<EventArgs<int>> ItemChanged;
+    event EventHandler Reset;
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleMatrix.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleMatrix.cs	(revision 9274)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+
+namespace HeuristicLab.Data {
+  public interface IStringConvertibleMatrix : IContent {
+    int Rows { get; set; }
+    int Columns { get; set; }
+    IEnumerable<string> ColumnNames { get; set; }
+    IEnumerable<string> RowNames { get; set; }
+
+    bool SortableView { get; set; }
+    bool ReadOnly { get; }
+
+    bool Validate(string value, out string errorMessage);
+    string GetValue(int rowIndex, int columnIndex);
+    bool SetValue(string value, int rowIndex, int columnIndex);
+
+    event EventHandler ColumnsChanged;
+    event EventHandler RowsChanged;
+    event EventHandler ColumnNamesChanged;
+    event EventHandler RowNamesChanged;
+    event EventHandler SortableViewChanged;
+    event EventHandler<EventArgs<int, int>> ItemChanged;
+    event EventHandler Reset;
+
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValue.cs	(revision 9274)
@@ -0,0 +1,35 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+
+namespace HeuristicLab.Data {
+  public interface IStringConvertibleValue : IContent {
+    bool ReadOnly { get; }
+
+    bool Validate(string value, out string errorMessage);
+    string GetValue();
+    bool SetValue(string value);
+
+    event EventHandler ValueChanged;
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValueTuple.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValueTuple.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValueTuple.cs	(revision 9274)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Core;
+namespace HeuristicLab.Data {
+  public interface IStringConvertibleValueTuple : IItem {
+    IStringConvertibleValue Item1 { get; }
+    IStringConvertibleValue Item2 { get; }
+    bool ReadOnly { get; }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentArray.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentArray.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentArray.cs	(revision 9274)
@@ -0,0 +1,80 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("PercentArray", "Represents an array of double values in percent.")]
+  [StorableClass]
+  public class PercentArray : DoubleArray {
+    [StorableConstructor]
+    protected PercentArray(bool deserializing) : base(deserializing) { }
+    protected PercentArray(PercentArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public PercentArray() : base() { }
+    public PercentArray(int length) : base(length) { }
+    public PercentArray(double[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PercentArray(this, cloner);
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (array.Length > 0) {
+        sb.Append(array[0].ToString("#0.#################### %"));  // percent format
+        for (int i = 1; i < array.Length; i++)
+          sb.Append(";").Append(array[i].ToString("#0.#################### %"));  // percent format
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      value = value.Replace("%", " ");
+      return base.Validate(value, out errorMessage);
+    }
+    protected override string GetValue(int index) {
+      return this[index].ToString("#0.#################### %");  // percent format
+    }
+    protected override bool SetValue(string value, int index) {
+      bool percent = value.Contains("%");
+      value = value.Replace("%", " ");
+      double val;
+      if (double.TryParse(value, out val)) {
+        if (percent) {
+          if (!(val).IsAlmost(this[index] * 100.0))
+            this[index] = val == 0 ? 0 : val / 100.0;
+        } else {
+          this[index] = val;
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentMatrix.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentMatrix.cs	(revision 9274)
@@ -0,0 +1,88 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("PercentMatrix", "Represents a matrix of double values in percent.")]
+  [StorableClass]
+  public class PercentMatrix : DoubleMatrix {
+    [StorableConstructor]
+    protected PercentMatrix(bool deserializing) : base(deserializing) { }
+    protected PercentMatrix(PercentMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public PercentMatrix() : base() { }
+    public PercentMatrix(int rows, int columns) : base(rows, columns) { }
+    public PercentMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public PercentMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
+    public PercentMatrix(double[,] elements) : base(elements) { }
+    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
+    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PercentMatrix(this, cloner);
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (matrix.Length > 0) {
+        for (int i = 0; i < Rows; i++) {
+          sb.Append("[").Append(matrix[i, 0].ToString("#0.#################### %"));  // percent format
+          for (int j = 1; j < Columns; j++)
+            sb.Append(";").Append(matrix[i, j].ToString("#0.#################### %"));  // percent format
+          sb.Append("]");
+        }
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      value = value.Replace("%", " ");
+      return base.Validate(value, out errorMessage);
+    }
+    protected override string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString("#0.#################### %");  // percent format
+    }
+    protected override bool SetValue(string value, int rowIndex, int columnIndex) {
+      bool percent = value.Contains("%");
+      value = value.Replace("%", " ");
+      double val;
+      if (double.TryParse(value, out val)) {
+        if (percent) {
+          if (!(val).IsAlmost(this[rowIndex, columnIndex] * 100.0))
+            this[rowIndex, columnIndex] = val == 0 ? 0 : val / 100.0;
+        } else {
+          this[rowIndex, columnIndex] = val;
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/PercentValue.cs	(revision 9274)
@@ -0,0 +1,70 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("PercentValue", "Represents a double value in percent.")]
+  [StorableClass]
+  public class PercentValue : DoubleValue {
+    [StorableConstructor]
+    protected PercentValue(bool deserializing) : base(deserializing) { }
+    protected PercentValue(PercentValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public PercentValue() : base() { }
+    public PercentValue(double value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PercentValue(this, cloner);
+    }
+
+    public override string ToString() {
+      return Value.ToString("#0.#################### %");  // percent format
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      value = value.Replace("%", " ");
+      return base.Validate(value, out errorMessage);
+    }
+    protected override string GetValue() {
+      return Value.ToString("#0.#################### %");  // percent format
+    }
+    protected override bool SetValue(string value) {
+      bool percent = value.Contains("%");
+      value = value.Replace("%", " ");
+      double val;
+      if (double.TryParse(value, out val)) {
+        if (percent) {
+          if (!(val).IsAlmost(Value * 100.0))
+            Value = val == 0 ? 0 : val / 100.0;
+        } else {
+          Value = val;
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Plugin.cs.frame
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Plugin.cs.frame	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Plugin.cs.frame	(revision 9274)
@@ -0,0 +1,36 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Data {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Data plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Data", "3.3.7.$WCREV$")]
+  [PluginFile("HeuristicLab.Data-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabDataPlugin : PluginBase {
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Properties/AssemblyInfo.cs.frame	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/Properties/AssemblyInfo.cs.frame	(revision 9274)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.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.Data")]
+[assembly: AssemblyDescription("HeuristicLab data classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2012 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("f1be1f44-c421-4749-9d25-160611dc18b3")]
+
+// 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.7.$WCREV$")]
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringArray.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringArray.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringArray.cs	(revision 9274)
@@ -0,0 +1,177 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("StringArray", "Represents an array of strings.")]
+  [StorableClass]
+  public class StringArray : Item, IEnumerable<string>, IStringConvertibleArray {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected string[] array;
+
+    public virtual int Length {
+      get { return array.Length; }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Length cannot be set. StringArray is read-only.");
+        if (value != Length) {
+          Array.Resize<string>(ref array, value);
+          OnReset();
+        }
+      }
+    }
+    public virtual string this[int index] {
+      get { return array[index]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
+        if (value != array[index]) {
+          if ((value != null) || (array[index] != string.Empty)) {
+            array[index] = value != null ? value : string.Empty;
+            OnItemChanged(index);
+          }
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected StringArray(bool deserializing) : base(deserializing) { }
+    protected StringArray(StringArray original, Cloner cloner)
+      : base(original, cloner) {
+      this.array = (string[])original.array.Clone();
+      this.readOnly = original.readOnly;
+    }
+    public StringArray() {
+      array = new string[0];
+      readOnly = false;
+    }
+    public StringArray(int length) {
+      array = new string[length];
+      for (int i = 0; i < array.Length; i++)
+        array[i] = string.Empty;
+      readOnly = false;
+    }
+    public StringArray(string[] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      array = new string[elements.Length];
+      for (int i = 0; i < array.Length; i++)
+        array[i] = elements[i] == null ? string.Empty : elements[i];
+      readOnly = false;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StringArray(this, cloner);
+    }
+
+    public virtual StringArray AsReadOnly() {
+      StringArray readOnlyStringArray = (StringArray)this.Clone();
+      readOnlyStringArray.readOnly = true;
+      return readOnlyStringArray;
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (array.Length > 0) {
+        sb.Append(array[0]);
+        for (int i = 1; i < array.Length; i++)
+          sb.Append(";").Append(array[i]);
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<string> GetEnumerator() {
+      return array.Cast<string>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      if (value == null) {
+        errorMessage = "Invalid Value (string must not be null)";
+        return false;
+      } else {
+        errorMessage = string.Empty;
+        return true;
+      }
+    }
+    protected virtual string GetValue(int index) {
+      return this[index];
+    }
+    protected virtual bool SetValue(string value, int index) {
+      if (value != null) {
+        this[index] = value;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    public event EventHandler<EventArgs<int>> ItemChanged;
+    protected virtual void OnItemChanged(int index) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int>(index));
+      OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    #region IStringConvertibleArray Members
+    int IStringConvertibleArray.Length {
+      get { return Length; }
+      set { Length = value; }
+    }
+    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleArray.GetValue(int index) {
+      return GetValue(index);
+    }
+    bool IStringConvertibleArray.SetValue(string value, int index) {
+      return SetValue(value, index);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringConvertibleValueTuple.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringConvertibleValueTuple.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringConvertibleValueTuple.cs	(revision 9274)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [StorableClass]
+  [Item("StringConvertibleValueTuple<,>", "A generic abstract base class for representing multiple values of a string convertible value.")]
+  public abstract class StringConvertibleValueTuple<T, U> : Item, IStringConvertibleValueTuple
+    where T : class, IDeepCloneable, IStringConvertibleValue
+    where U : class, IDeepCloneable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.ValueType; }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [Storable(Name = "Values")]
+    protected Tuple<T, U> values;
+
+    protected T Item1 { get { return values.Item1; } }
+    IStringConvertibleValue IStringConvertibleValueTuple.Item1 { get { return Item1; } }
+    protected U Item2 { get { return values.Item2; } }
+    IStringConvertibleValue IStringConvertibleValueTuple.Item2 { get { return Item2; } }
+
+    [StorableConstructor]
+    protected StringConvertibleValueTuple(bool deserializing)
+      : base(deserializing) {
+    }
+    protected StringConvertibleValueTuple(StringConvertibleValueTuple<T, U> original, Cloner cloner)
+      : base(original, cloner) {
+      T item1 = (T)cloner.Clone(original.values.Item1);
+      U item2 = (U)cloner.Clone(original.values.Item2);
+      values = Tuple.Create<T, U>(item1, item2);
+      RegisterEventHandler();
+    }
+
+    public StringConvertibleValueTuple(T item1, U item2)
+      : base() {
+      values = Tuple.Create<T, U>(item1, item2);
+      readOnly = false;
+      RegisterEventHandler();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandler();
+    }
+
+
+    public abstract StringConvertibleValueTuple<T, U> AsReadOnly();
+
+    public override string ToString() {
+      return string.Format("Item1: {0}, Item2: {1}", Item1, Item2);
+    }
+
+    private void RegisterEventHandler() {
+      Item1.ValueChanged += Item_ValueChanged;
+      Item2.ValueChanged += Item_ValueChanged;
+    }
+
+    private void Item_ValueChanged(object sender, EventArgs e) {
+      OnValueChanged();
+    }
+
+    public event EventHandler ValueChanged;
+    protected virtual void OnValueChanged() {
+      if (ValueChanged != null)
+        ValueChanged(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 9274)
@@ -0,0 +1,318 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("StringMatrix", "Represents a matrix of strings.")]
+  [StorableClass]
+  public class StringMatrix : Item, IEnumerable<string>, IStringConvertibleMatrix {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected string[,] matrix;
+
+    [Storable]
+    protected List<string> columnNames;
+    public virtual IEnumerable<string> ColumnNames {
+      get { return this.columnNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. StringMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          columnNames = new List<string>();
+        else if (value.Count() != Columns)
+          throw new ArgumentException("A column name must be specified for each column .");
+        else
+          columnNames = new List<string>(value);
+        OnColumnNamesChanged();
+      }
+    }
+    [Storable]
+    protected List<string> rowNames;
+    public virtual IEnumerable<string> RowNames {
+      get { return this.rowNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. StringMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          rowNames = new List<string>();
+        else if (value.Count() != Rows)
+          throw new ArgumentException("A row name must be specified for each row.");
+        else
+          rowNames = new List<string>(value);
+        OnRowNamesChanged();
+      }
+    }
+    [Storable]
+    protected bool sortableView;
+    public virtual bool SortableView {
+      get { return sortableView; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("SortableView cannot be set. StringMatrix is read-only.");
+        if (value != sortableView) {
+          sortableView = value;
+          OnSortableViewChanged();
+        }
+      }
+    }
+
+    public virtual int Rows {
+      get { return matrix.GetLength(0); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. StringMatrix is read-only.");
+        if (value != Rows) {
+          string[,] newMatrix = new string[value, Columns];
+          Array.Copy(matrix, newMatrix, Math.Min(value * Columns, matrix.Length));
+          matrix = newMatrix;
+          while (rowNames.Count > value)
+            rowNames.RemoveAt(rowNames.Count - 1);
+          while (rowNames.Count < value)
+            rowNames.Add("Row " + rowNames.Count);
+          OnRowsChanged();
+          OnRowNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual int Columns {
+      get { return matrix.GetLength(1); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. StringMatrix is read-only.");
+        if (value != Columns) {
+          string[,] newMatrix = new string[Rows, value];
+          for (int i = 0; i < Rows; i++)
+            Array.Copy(matrix, i * Columns, newMatrix, i * value, Math.Min(value, Columns));
+          matrix = newMatrix;
+          while (columnNames.Count > value)
+            columnNames.RemoveAt(columnNames.Count - 1);
+          while (columnNames.Count < value)
+            columnNames.Add("Column " + columnNames.Count);
+          OnColumnsChanged();
+          OnColumnNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual string this[int rowIndex, int columnIndex] {
+      get { return matrix[rowIndex, columnIndex]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringMatrix is read-only.");
+        if (value != matrix[rowIndex, columnIndex]) {
+          if ((value != null) || (matrix[rowIndex, columnIndex] != string.Empty)) {
+            matrix[rowIndex, columnIndex] = value != null ? value : string.Empty;
+            OnItemChanged(rowIndex, columnIndex);
+          }
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected StringMatrix(bool deserializing) : base(deserializing) { }
+    protected StringMatrix(StringMatrix original, Cloner cloner)
+      : base(original, cloner) {
+      this.matrix = (string[,])original.matrix.Clone();
+      this.columnNames = new List<string>(original.columnNames);
+      this.rowNames = new List<string>(original.rowNames);
+      this.sortableView = original.sortableView;
+      this.readOnly = original.readOnly;
+    }
+    public StringMatrix() {
+      matrix = new string[0, 0];
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    public StringMatrix(int rows, int columns) {
+      matrix = new string[rows, columns];
+      for (int i = 0; i < matrix.GetLength(0); i++) {
+        for (int j = 0; j < matrix.GetLength(1); j++)
+          matrix[i, j] = string.Empty;
+      }
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames)
+      : this(rows, columns) {
+      ColumnNames = columnNames;
+    }
+    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(rows, columns, columnNames) {
+      RowNames = rowNames;
+    }
+    public StringMatrix(string[,] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      matrix = new string[elements.GetLength(0), elements.GetLength(1)];
+      for (int i = 0; i < matrix.GetLength(0); i++) {
+        for (int j = 0; j < matrix.GetLength(1); j++)
+          matrix[i, j] = elements[i, j] == null ? string.Empty : elements[i, j];
+      }
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames)
+      : this(elements) {
+      ColumnNames = columnNames;
+    }
+    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(elements, columnNames) {
+      RowNames = rowNames;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StringMatrix(this, cloner);
+    }
+
+    public virtual StringMatrix AsReadOnly() {
+      StringMatrix readOnlyStringMatrix = (StringMatrix)this.Clone();
+      readOnlyStringMatrix.readOnly = true;
+      return readOnlyStringMatrix;
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (matrix.Length > 0) {
+        for (int i = 0; i < Rows; i++) {
+          sb.Append("[").Append(matrix[i, 0]);
+          for (int j = 1; j < Columns; j++)
+            sb.Append(";").Append(matrix[i, j]);
+          sb.Append("]");
+        }
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<string> GetEnumerator() {
+      return matrix.Cast<string>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      if (value == null) {
+        errorMessage = "Invalid Value (string must not be null)";
+        return false;
+      } else {
+        errorMessage = string.Empty;
+        return true;
+      }
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex];
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      if (value != null) {
+        this[rowIndex, columnIndex] = value;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region events
+    public event EventHandler ColumnsChanged;
+    protected virtual void OnColumnsChanged() {
+      EventHandler handler = ColumnsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowsChanged;
+    protected virtual void OnRowsChanged() {
+      EventHandler handler = RowsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ColumnNamesChanged;
+    protected virtual void OnColumnNamesChanged() {
+      EventHandler handler = ColumnNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowNamesChanged;
+    protected virtual void OnRowNamesChanged() {
+      EventHandler handler = RowNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler SortableViewChanged;
+    protected virtual void OnSortableViewChanged() {
+      EventHandler handler = SortableViewChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<int, int>> ItemChanged;
+    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
+      OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+    #endregion
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/StringValue.cs	(revision 9274)
@@ -0,0 +1,135 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("StringValue", "Represents a string.")]
+  [StorableClass]
+  public class StringValue : Item, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    [Storable]
+    protected string value;
+    public virtual string Value {
+      get { return value; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Value cannot be set. StringValue is read-only.");
+        if (value != this.value) {
+          if ((value != null) || (this.value != string.Empty)) {
+            this.value = value != null ? value : string.Empty;
+            OnValueChanged();
+          }
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected StringValue(bool deserializing) : base(deserializing) { }
+    protected StringValue(StringValue original, Cloner cloner)
+      : base(original, cloner) {
+      this.value = original.value != null ? original.value : string.Empty;
+      this.readOnly = original.readOnly;
+    }
+    public StringValue() {
+      this.value = string.Empty;
+      this.readOnly = false;
+    }
+    public StringValue(string value) {
+      this.value = value != null ? value : string.Empty;
+      this.readOnly = false;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StringValue(this, cloner);
+    }
+
+    public virtual StringValue AsReadOnly() {
+      StringValue readOnlyStringValue = (StringValue)this.Clone();
+      readOnlyStringValue.readOnly = true;
+      return readOnlyStringValue;
+    }
+
+    public override string ToString() {
+      return value;
+    }
+
+    public virtual int CompareTo(object obj) {
+      StringValue other = obj as StringValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    public event EventHandler ValueChanged;
+    protected virtual void OnValueChanged() {
+      if (ValueChanged != null)
+        ValueChanged(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      if (value == null) {
+        errorMessage = "Invalid Value (string must not be null)";
+        return false;
+      } else {
+        errorMessage = string.Empty;
+        return true;
+      }
+    }
+    protected virtual string GetValue() {
+      return Value;
+    }
+    protected virtual bool SetValue(string value) {
+      if (value != null) {
+        Value = value;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/TimeSpanValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/TimeSpanValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/TimeSpanValue.cs	(revision 9274)
@@ -0,0 +1,90 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("TimeSpanValue", "Represents a duration of time.")]
+  [StorableClass]
+  public class TimeSpanValue : ValueTypeValue<TimeSpan>, IComparable, IStringConvertibleValue {
+    [StorableConstructor]
+    protected TimeSpanValue(bool deserializing) : base(deserializing) { }
+    protected TimeSpanValue(TimeSpanValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public TimeSpanValue() : base() { }
+    public TimeSpanValue(TimeSpan value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSpanValue(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      TimeSpanValue other = obj as TimeSpanValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      TimeSpan val;
+      bool valid = TimeSpan.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetTimeSpanFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString();
+    }
+    protected virtual bool SetValue(string value) {
+      TimeSpan val;
+      if (TimeSpan.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeArray.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 9274)
@@ -0,0 +1,133 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("ValueTypeArray", "An abstract base class for representing arrays of value types.")]
+  [StorableClass]
+  public abstract class ValueTypeArray<T> : Item, IEnumerable<T> where T : struct {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected T[] array;
+
+    public virtual int Length {
+      get { return array.Length; }
+      #region Mono Compatibility
+      // this setter should be protected, but the Mono compiler couldn't handle it
+      set {
+        if (ReadOnly) throw new NotSupportedException("Length cannot be set. ValueTypeArray is read-only.");
+        if (value != Length) {
+          Array.Resize<T>(ref array, value);
+          OnReset();
+        }
+      }
+      #endregion
+    }
+    public virtual T this[int index] {
+      get { return array[index]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeArray is read-only.");
+        if (!value.Equals(array[index])) {
+          array[index] = value;
+          OnItemChanged(index);
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected ValueTypeArray(bool deserializing) : base(deserializing) { }
+    protected ValueTypeArray(ValueTypeArray<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.array = (T[])original.array.Clone();
+      this.readOnly = original.readOnly;
+    }
+    protected ValueTypeArray() {
+      array = new T[0];
+      readOnly = false;
+    }
+    protected ValueTypeArray(int length) {
+      array = new T[length];
+      readOnly = false;
+    }
+    protected ValueTypeArray(T[] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      array = (T[])elements.Clone();
+      readOnly = false;
+    }
+
+    public virtual ValueTypeArray<T> AsReadOnly() {
+      ValueTypeArray<T> readOnlyValueTypeArray = (ValueTypeArray<T>)this.Clone();
+      readOnlyValueTypeArray.readOnly = true;
+      return readOnlyValueTypeArray;
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (array.Length > 0) {
+        sb.Append(array[0].ToString());
+        for (int i = 1; i < array.Length; i++)
+          sb.Append(";").Append(array[i].ToString());
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<T> GetEnumerator() {
+      return array.Cast<T>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    public event EventHandler<EventArgs<int>> ItemChanged;
+    protected virtual void OnItemChanged(int index) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int>(index));
+      OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeMatrix.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeMatrix.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeMatrix.cs	(revision 9274)
@@ -0,0 +1,263 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("ValueTypeMatrix", "An abstract base class for representing matrices of value types.")]
+  [StorableClass]
+  public abstract class ValueTypeMatrix<T> : Item, IEnumerable<T> where T : struct {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected T[,] matrix;
+
+    [Storable]
+    protected List<string> columnNames;
+    public virtual IEnumerable<string> ColumnNames {
+      get { return this.columnNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. ValueTypeMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          columnNames = new List<string>();
+        else if (value.Count() != Columns)
+          throw new ArgumentException("A column name must be specified for each column.");
+        else
+          columnNames = new List<string>(value);
+        OnColumnNamesChanged();
+      }
+    }
+    [Storable]
+    protected List<string> rowNames;
+    public virtual IEnumerable<string> RowNames {
+      get { return this.rowNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. ValueTypeMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          rowNames = new List<string>();
+        else if (value.Count() != Rows)
+          throw new ArgumentException("A row name must be specified for each row.");
+        else
+          rowNames = new List<string>(value);
+        OnRowNamesChanged();
+      }
+    }
+    [Storable]
+    protected bool sortableView;
+    public virtual bool SortableView {
+      get { return sortableView; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("SortableView cannot be set. ValueTypeMatrix is read-only.");
+        if (value != sortableView) {
+          sortableView = value;
+          OnSortableViewChanged();
+        }
+      }
+    }
+
+    public virtual int Rows {
+      get { return matrix.GetLength(0); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. ValueTypeMatrix is read-only.");
+        if (value != Rows) {
+          T[,] newArray = new T[value, Columns];
+          Array.Copy(matrix, newArray, Math.Min(value * Columns, matrix.Length));
+          matrix = newArray;
+          while (rowNames.Count > value)
+            rowNames.RemoveAt(rowNames.Count - 1);
+          while (rowNames.Count < value)
+            rowNames.Add("Row " + rowNames.Count);
+          OnRowsChanged();
+          OnRowNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual int Columns {
+      get { return matrix.GetLength(1); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. ValueTypeMatrix is read-only.");
+        if (value != Columns) {
+          T[,] newArray = new T[Rows, value];
+          for (int i = 0; i < Rows; i++)
+            Array.Copy(matrix, i * Columns, newArray, i * value, Math.Min(value, Columns));
+          matrix = newArray;
+          while (columnNames.Count > value)
+            columnNames.RemoveAt(columnNames.Count - 1);
+          while (columnNames.Count < value)
+            columnNames.Add("Column " + columnNames.Count);
+          OnColumnsChanged();
+          OnColumnNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual T this[int rowIndex, int columnIndex] {
+      get { return matrix[rowIndex, columnIndex]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeMatrix is read-only.");
+        if (!value.Equals(matrix[rowIndex, columnIndex])) {
+          matrix[rowIndex, columnIndex] = value;
+          OnItemChanged(rowIndex, columnIndex);
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected ValueTypeMatrix(bool deserializing) : base(deserializing) { }
+    protected ValueTypeMatrix(ValueTypeMatrix<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.matrix = (T[,])original.matrix.Clone();
+      this.columnNames = new List<string>(original.columnNames);
+      this.rowNames = new List<string>(original.rowNames);
+      this.sortableView = original.sortableView;
+      this.readOnly = original.readOnly;
+    }
+    protected ValueTypeMatrix() {
+      matrix = new T[0, 0];
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected ValueTypeMatrix(int rows, int columns) {
+      matrix = new T[rows, columns];
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected ValueTypeMatrix(int rows, int columns, IEnumerable<string> columnNames)
+      : this(rows, columns) {
+      ColumnNames = columnNames;
+    }
+    protected ValueTypeMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(rows, columns, columnNames) {
+      RowNames = rowNames;
+    }
+    protected ValueTypeMatrix(T[,] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      matrix = (T[,])elements.Clone();
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames)
+      : this(elements) {
+      ColumnNames = columnNames;
+    }
+    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(elements, columnNames) {
+      RowNames = rowNames;
+    }
+
+    public virtual ValueTypeMatrix<T> AsReadOnly() {
+      ValueTypeMatrix<T> readOnlyValueTypeMatrix = (ValueTypeMatrix<T>)this.Clone();
+      readOnlyValueTypeMatrix.readOnly = true;
+      return readOnlyValueTypeMatrix;
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (matrix.Length > 0) {
+        for (int i = 0; i < Rows; i++) {
+          sb.Append("[").Append(matrix[i, 0].ToString());
+          for (int j = 1; j < Columns; j++)
+            sb.Append(";").Append(matrix[i, j].ToString());
+          sb.Append("]");
+        }
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<T> GetEnumerator() {
+      return matrix.Cast<T>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    #region events
+    public event EventHandler ColumnsChanged;
+    protected virtual void OnColumnsChanged() {
+      EventHandler handler = ColumnsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowsChanged;
+    protected virtual void OnRowsChanged() {
+      EventHandler handler = RowsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ColumnNamesChanged;
+    protected virtual void OnColumnNamesChanged() {
+      EventHandler handler = ColumnNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowNamesChanged;
+    protected virtual void OnRowNamesChanged() {
+      EventHandler handler = RowNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler SortableViewChanged;
+    protected virtual void OnSortableViewChanged() {
+      EventHandler handler = SortableViewChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<int, int>> ItemChanged;
+    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
+      OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+    #endregion
+  }
+}
Index: /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeValue.cs
===================================================================
--- /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeValue.cs	(revision 9274)
+++ /branches/ImprovingStringConvertibleMatrix/HeuristicLab.Data/3.3/ValueTypeValue.cs	(revision 9274)
@@ -0,0 +1,88 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("ValueTypeValue", "An abstract base class for representing values of value types.")]
+  [StorableClass]
+  public abstract class ValueTypeValue<T> : Item where T : struct {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.ValueType; }
+    }
+
+    [Storable]
+    protected T value;
+    public virtual T Value {
+      get { return value; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Value cannot be set. ValueTypeValue is read-only.");
+        if (!value.Equals(this.value)) {
+          this.value = value;
+          OnValueChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected ValueTypeValue(bool deserializing) : base(deserializing) { }
+    protected ValueTypeValue(ValueTypeValue<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.value = original.value;
+      this.readOnly = original.readOnly;
+    }
+    protected ValueTypeValue() {
+      this.value = default(T);
+      this.readOnly = false;
+    }
+    protected ValueTypeValue(T value) {
+      this.value = value;
+      this.readOnly = false;
+    }
+
+    public virtual ValueTypeValue<T> AsReadOnly() {
+      ValueTypeValue<T> readOnlyValueTypeValue = (ValueTypeValue<T>)this.Clone();
+      readOnlyValueTypeValue.readOnly = true;
+      return readOnlyValueTypeValue;
+    }
+
+    public override string ToString() {
+      return value.ToString();
+    }
+
+    public event EventHandler ValueChanged;
+    protected virtual void OnValueChanged() {
+      if (ValueChanged != null)
+        ValueChanged(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+  }
+}
