Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 17402)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 17403)
@@ -450,6 +450,10 @@
     string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
       var value = variableValues[variableNames[columnIndex]][rowIndex];
-      if (value is IVector vector)
-        return $"[{string.Join(", ", vector.Cast<object>())}]";
+      if (value is IVector vector) {
+        const int maxCount = 10;
+        string extension = vector.Count > maxCount ? ", ..." : "";
+        return $"[{string.Join(", ", vector.Cast<object>().Take(Math.Min(vector.Count, maxCount)))}{extension}]";
+      }
+
       return value.ToString();
     }
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IVector.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IVector.cs	(revision 17402)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IVector.cs	(revision 17403)
@@ -6,4 +6,5 @@
   [StorableType("E6B5D191-F094-4A6C-91C1-011191C13A16")]
   public interface IVector : IEnumerable {
+    int Count { get; }
   }
 
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/TimeSeries/TimeSeriesInstanceProvider.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/TimeSeries/TimeSeriesInstanceProvider.cs	(revision 17402)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.Instances.DataAnalysis/3.3/Classification/TimeSeries/TimeSeriesInstanceProvider.cs	(revision 17403)
@@ -58,18 +58,27 @@
         using (var trainingReader = new StreamReader(trainingEntry.Open()))
         using (var testReader = new StreamReader(testEntry.Open())) {
-          ParseMetadata(trainingReader, out var inputVariables, out string targetVariable);
-          ParseMetadata(testReader, out _, out _); // ignore outputs
+          ParseMetadata(trainingReader, out var inputVariables, out string targetVariable, out var classLabels);
+          ParseMetadata(testReader, out _, out _, out _); // ignore outputs
 
           // Read data
           var inputsData = new List<DoubleVector>[inputVariables.Count];
           for (int i = 0; i < inputsData.Length; i++) inputsData[i] = new List<DoubleVector>();
-          var targetData = new List<double>();
+          bool numericTarget = classLabels.All(label => !double.IsNaN(ParseNumber(label)));
+          IList targetData = numericTarget ? new List<double>() : new List<string>() as IList;
           ReadData(trainingReader, inputsData, targetData, out int numTrainingRows);
           ReadData(testReader, inputsData, targetData, out int numTestRows);
+
+          // Translate class values to numeric values
+          if (targetData is List<string> stringTargetData) {
+            var labelTranslation = classLabels
+              .Select((x, i) => new { Label = x, i })
+              .ToDictionary(x => x.Label, x => (double)x.i);
+            targetData = stringTargetData.Select(label => labelTranslation[label]).ToList();
+          }
 
           // Build dataset
           var dataset = new Dataset(
             inputVariables.Concat(new[] { targetVariable }),
-            inputsData.Cast<IList>().Concat(new[] { targetData })
+            inputsData.Concat(new[] { targetData })
           );
           Debug.Assert(dataset.Rows == numTrainingRows + numTestRows);
@@ -90,7 +99,9 @@
     }
 
-    private static void ParseMetadata(StreamReader reader, out List<string> inputVariables, out string targetVariable) {
+    private static void ParseMetadata(StreamReader reader, out List<string> inputVariables, out string targetVariable, out List<string> classLabels) {
       int nrOfInputs = 0;
+      IEnumerable<string> labels = null;
       bool dataStart = false;
+
       while (!reader.EndOfStream && !dataStart) {
         var line = reader.ReadLine();
@@ -101,5 +112,5 @@
           var type = splits.First();
           var arguments = splits.Skip(1).ToList();
-          switch (type.ToLowerInvariant()) {
+          switch (type) {
             case "@univariate":
               bool univariate = bool.Parse(arguments[0]);
@@ -111,4 +122,9 @@
               nrOfInputs = dimensions;
               break;
+            case "@classLabel":
+              bool containLabels = bool.Parse(arguments[0]);
+              if (containLabels)
+                labels = arguments.Skip(1);
+              break;
             case "@data":
               dataStart = true;
@@ -126,7 +142,12 @@
 
       targetVariable = "Y";
-    }
-
-    private static void ReadData(StreamReader reader, List<DoubleVector>[] inputsData, List<double> targetData, out int count) {
+
+      classLabels = labels.ToList();
+    }
+
+    private static void ReadData(StreamReader reader, List<DoubleVector>[] inputsData, IList targetData, out int count) {
+      var numericTargetData = targetData as List<double>;
+      var stringTargetData = targetData as List<string>;
+
       count = 0;
       while (!reader.EndOfStream) {
@@ -139,14 +160,23 @@
           var numbers = variable
             .Split(',')
-            .Select(d => double.Parse(d, CultureInfo.InvariantCulture))
+            .Select(ParseNumber)
             .ToList();
           inputsData[i].Add(new DoubleVector(numbers));
         }
 
-        var target = double.Parse(variables[variables.Length - 1], CultureInfo.InvariantCulture);
-        targetData.Add(target);
+        var target = variables[variables.Length - 1];
+        if (numericTargetData != null) numericTargetData.Add(ParseNumber(target));
+        else if (stringTargetData != null) stringTargetData.Add(target);
+        else throw new InvalidOperationException("Target must either be numeric or a string.");
 
         count++;
       }
+    }
+
+    private static double ParseNumber(string number) {
+      return
+        double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out double parsed)
+          ? parsed
+          : double.NaN;
     }
 
