Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TupleSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TupleSerializer.cs	(revision 5698)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TupleSerializer.cs	(revision 5698)
@@ -0,0 +1,96 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Persistence.Interfaces;
+
+namespace HeuristicLab.Persistence.Default.CompositeSerializers {
+
+  [StorableClass]
+  internal sealed class TupleSerializer : ICompositeSerializer {
+
+    [StorableConstructor]
+    private TupleSerializer(bool deserializing) { }
+    public TupleSerializer() { }
+
+    public int Priority {
+      get { return 50; }
+    }
+
+    public bool CanSerialize(Type type) {
+      if (!type.IsGenericType)
+        return false;
+      Type t = type.GetGenericTypeDefinition();
+      return t == typeof(Tuple<>) ||
+        t == typeof(Tuple<,>) ||
+        t == typeof(Tuple<,,>) ||
+        t == typeof(Tuple<,,,>) ||
+        t == typeof(Tuple<,,,,>) ||
+        t == typeof(Tuple<,,,,,>) ||
+        t == typeof(Tuple<,,,,,,>) ||
+        t == typeof(Tuple<,,,,,,,>);
+    }
+
+    public string JustifyRejection(Type type) {
+      if (!type.IsGenericType)
+        return "not a generic type";
+      return "type is not a tuple type";
+    }
+
+    public IEnumerable<Tag> CreateMetaInfo(object obj) {
+      Type t = obj.GetType();
+      for (int i = 1; i<=t.GetGenericArguments().Length; i++) {
+        string name = string.Format("Item{0}", i);
+        yield return new Tag(name, t.GetProperty(name).GetValue(obj, null));
+      }
+    }
+
+    public IEnumerable<Tag> Decompose(object obj) {
+      return null;
+    }
+
+    private static BindingFlags public_static = BindingFlags.Public | BindingFlags.Static;
+
+    private static MethodInfo[] CreateMethods = new MethodInfo[8];
+
+    static TupleSerializer() {
+      foreach (MethodInfo mi in typeof(Tuple).GetMethods(public_static).Where(mi => mi.Name == "Create")) {
+        CreateMethods[mi.GetGenericArguments().Length-1] = mi;
+      }
+    }
+
+    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
+      var values = metaInfo.Select(t => t.Value).ToArray();
+      MethodInfo createMethod = CreateMethods[values.Length-1].MakeGenericMethod(values.Select(v => v.GetType()).ToArray());
+      return createMethod.Invoke(null, values.ToArray());
+    }
+
+    public void Populate(object instance, IEnumerable<Tag> tags, Type type) {
+      // nothing to do
+    }
+
+  }
+}
Index: /trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 5697)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 5698)
@@ -142,4 +142,5 @@
     <Compile Include="Default\CompositeSerializers\CompactNumberArray2StringSerializer.cs" />
     <Compile Include="Default\CompositeSerializers\ConcreteDictionarySerializer.cs" />
+    <Compile Include="Default\CompositeSerializers\TupleSerializer.cs" />
     <Compile Include="Default\CompositeSerializers\HashSetSerializer.cs" />
     <Compile Include="Default\CompositeSerializers\DictionarySerializer.cs" />
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 5697)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 5698)
@@ -1243,4 +1243,16 @@
     }
 
+    [TestMethod]
+    public void TupleTest() {
+      var t1 = Tuple.Create(1);
+      var t2 = Tuple.Create('1', "2");
+      var t3 = Tuple.Create(3.0, 3f, 5);
+      var t4 = Tuple.Create(Tuple.Create(1, 2, 3), Tuple.Create(4, 5, 6), Tuple.Create(8, 9, 10));
+      var tuple = Tuple.Create(t1, t2, t3, t4);
+      XmlGenerator.Serialize(tuple, tempFile);
+      var newTuple = XmlParser.Deserialize<Tuple<Tuple<int>, Tuple<char, string>, Tuple<double, float, int>, Tuple<Tuple<int, int, int>, Tuple<int, int, int>, Tuple<int, int, int>>>>(tempFile);
+      Assert.AreEqual(tuple, newTuple);
+    }
+
 
 
