Index: branches/New Persistence Exploration/Persistence/Persistence/NewSerializationTest.cs
===================================================================
--- branches/New Persistence Exploration/Persistence/Persistence/NewSerializationTest.cs	(revision 1264)
+++ branches/New Persistence Exploration/Persistence/Persistence/NewSerializationTest.cs	(revision 1274)
@@ -3,4 +3,5 @@
 using System.Text;
 using System.Collections;
+using System.IO;
 
 namespace Persistence {
@@ -14,4 +15,6 @@
     [Storable]
     public ArrayList intArray = new ArrayList(new int[] { 1, 2, 3 });
+    [Storable]
+    public List<int> intList = new List<int>(new int[] { 321, 312, 321 });
     [Storable]
     public Custom c; 
@@ -38,7 +41,15 @@
       Serializer s = new Serializer(r, serializers);
       Persistence.XmlFormatter xmlFormatter = new Persistence.XmlFormatter();
+      StreamWriter writer = new StreamWriter("test.xml");
       foreach (ISerializationToken token in s) {
-        Console.Write(xmlFormatter.Format(token));
+        string line = xmlFormatter.Format(token);
+        writer.Write(line);
+        Console.Out.Write(line);
       }
+      writer.Close();
+      XmlParser parser = new XmlParser(new StreamReader("test.xml"));
+      DeSerializer deSerializer = new DeSerializer();      
+      object o = deSerializer.DeSerialize(parser);
+      Console.Out.WriteLine(Util.AutoFormat(o, true));
       Console.In.ReadLine();
     }
Index: branches/New Persistence Exploration/Persistence/Persistence/Persistence.csproj
===================================================================
--- branches/New Persistence Exploration/Persistence/Persistence/Persistence.csproj	(revision 1264)
+++ branches/New Persistence Exploration/Persistence/Persistence/Persistence.csproj	(revision 1274)
@@ -49,4 +49,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Util.cs" />
     <Compile Include="StorableAttributeTests.cs" />
     <Compile Include="StorableAttribute.cs" />
Index: branches/New Persistence Exploration/Persistence/Persistence/PersistenceManager.cs
===================================================================
--- branches/New Persistence Exploration/Persistence/Persistence/PersistenceManager.cs	(revision 1264)
+++ branches/New Persistence Exploration/Persistence/Persistence/PersistenceManager.cs	(revision 1274)
@@ -5,4 +5,5 @@
 using System.Collections;
 using System.Reflection;
+using System.Xml;
 
 namespace Persistence {
@@ -85,5 +86,5 @@
   #endregion
 
-  #region Generics (incomplete)
+  #region Custom
   public interface ICustomSerializer {
     bool CanSerialize(Type type);
@@ -127,9 +128,18 @@
     }
 
-    public object DeSerialize(IEnumerable o, Type t) {
-      throw new NotImplementedException();
-    }
-
-  }
+    public object DeSerialize(IEnumerable elements, Type t) {
+      List<object> allElements = new List<object>();
+      foreach (object obj in elements) {
+        allElements.Add(obj);
+      }
+      Array array = 
+        Array.CreateInstance(t.GetElementType(), allElements.Count);
+      for (int i = 0; i < array.Length; i++) {
+        array.SetValue(allElements[i], i);
+      }
+      return array;
+    }
+
+  }  
   #endregion
 
@@ -172,9 +182,9 @@
 
     private IEnumerator<ISerializationToken> Serialize(DataMemberAccessor accessor) {
-      object value = accessor.Get();
+      object value = accessor.Get();      
       if (value == null) {
         yield return new NullReferenceToken(accessor.Name);
-      } else if (this.primitiveSerializers.ContainsKey(accessor.Type)) {
-        yield return new PrimitiveToken(accessor, this.primitiveSerializers[accessor.Type].Serialize(value));
+      } else if (this.primitiveSerializers.ContainsKey(value.GetType())) {
+        yield return new PrimitiveToken(accessor, this.primitiveSerializers[value.GetType()].Serialize(value));
       } else if (this.obj2id.ContainsKey(value)) {
         yield return new ReferenceToken(accessor.Name, this.obj2id[value]);
@@ -183,5 +193,5 @@
         this.obj2id.Add(value, id);
         yield return new BeginToken(accessor, id);
-        ICustomSerializer customSerializer = this.FindCustomSerializer(accessor.Type);
+        ICustomSerializer customSerializer = this.FindCustomSerializer(value.GetType());
         if (customSerializer != null) {
           foreach (object obj in customSerializer.Serialize(value)) {
@@ -200,5 +210,5 @@
         yield return new EndToken(accessor, id);        
       }
-    }
+    }    
 
     private ICustomSerializer FindCustomSerializer(Type type) {
@@ -209,4 +219,119 @@
       return null;
     }                
+  }
+
+  public class DeSerializer {    
+
+    class AccessibleObject {
+      public object obj;
+      public Dictionary<string, DataMemberAccessor> accessorDict;
+      public List<object> customValues;
+      public AccessibleObject(object obj, Dictionary<string, DataMemberAccessor> accessorDict) {
+        this.obj = obj;
+        this.accessorDict = new Dictionary<string, DataMemberAccessor>();
+        this.customValues = new List<object>();
+        foreach (KeyValuePair<string, DataMemberAccessor> pair in accessorDict) {
+          this.accessorDict.Add(
+            pair.Value.Name,
+            pair.Value);
+        }
+      }
+      public void SetValue(string name, object value) {
+        if (name == "") {
+          customValues.Add(value);
+        } else {
+          accessorDict[name].Set(value);
+        }
+      }
+      public void SetAllDefaultValues() {
+      }
+    }
+
+    private delegate void Handler(IParseToken token);
+
+    private Dictionary<int, object> id2obj;
+    private Dictionary<Type, Handler> handlers;
+    private Stack<AccessibleObject> compositeStack;    
+
+    private Dictionary<Type, IPrimitiveSerializer> primitiveSerializers;
+    private List<ICustomSerializer> customSerializers;
+
+    public DeSerializer() {
+      id2obj = new Dictionary<int, object>();
+      compositeStack = new Stack<AccessibleObject>();
+      handlers = new Dictionary<Type, Handler>();
+      handlers.Add(typeof(CompositeStart), new Handler(CompositeStartHandler));
+      handlers.Add(typeof(CompositeEnd), new Handler(CompositeEndHandler));
+      handlers.Add(typeof(Primitive), new Handler(PrimitiveHandler));
+      handlers.Add(typeof(Reference), new Handler(ReferenceHandler));
+      handlers.Add(typeof(Null), new Handler(NullHandler));
+      // TODO: make this configurable
+      primitiveSerializers = new Dictionary<Type, IPrimitiveSerializer>();
+      primitiveSerializers.Add(typeof(int), new Int2XMLSerializer());
+      primitiveSerializers.Add(typeof(string), new String2XMLSerializer());
+      customSerializers = new List<ICustomSerializer>();
+      customSerializers.Add(new ArraySerializer());
+      customSerializers.Add(new EnumerableSerializer());      
+    }
+    public object DeSerialize(IEnumerable<IParseToken> tokens) {
+      foreach (IParseToken token in tokens) {
+        handlers[token.GetType()].Invoke(token);
+      }
+      return compositeStack.Pop().obj;
+    }
+    private void CompositeStartHandler(IParseToken token) {
+      CompositeStart start = (CompositeStart)token;
+      object instance = null;
+      if (this.FindCustomSerializer(start.Type) != null) {
+        instance = null;
+        compositeStack.Push(new AccessibleObject(null, new Dictionary<string, DataMemberAccessor>()));
+        id2obj.Add(start.Id, null);
+        // TODO: add warning proxy
+      } else {
+        instance = Activator.CreateInstance(start.Type);
+        Dictionary<string, DataMemberAccessor> accessorDict =
+        StorableAttribute.GetAutostorableAccessors(instance);
+        compositeStack.Push(new AccessibleObject(instance, accessorDict));
+        id2obj.Add(start.Id, instance);
+      }
+    }
+    private void CompositeEndHandler(IParseToken token) {
+      CompositeEnd end = (CompositeEnd)token;
+      AccessibleObject accessibleObject = compositeStack.Pop();
+      ICustomSerializer customSerializer = this.FindCustomSerializer(end.Type);
+      if (customSerializer != null) {
+        this.SetValue(end.Name,
+          customSerializer.DeSerialize(accessibleObject.customValues, end.Type));
+      } else {
+        this.SetValue(end.Name, accessibleObject.obj);
+      }
+    }
+    private ICustomSerializer FindCustomSerializer(Type type) {
+      foreach (ICustomSerializer serializer in customSerializers) {
+        if (serializer.CanSerialize(type))
+          return serializer;
+      }
+      return null;
+    }
+    private void PrimitiveHandler(IParseToken token) {
+      Primitive primitive = (Primitive)token;
+      object value = primitiveSerializers[primitive.Type].DeSerialize(primitive.SerializedValue);
+      this.SetValue(primitive.Name, value);     
+    }
+    private void ReferenceHandler(IParseToken token) {
+      Reference reference = (Reference)token;      
+      this.SetValue(reference.Name, this.id2obj[reference.Id]);            
+    }
+    private void NullHandler(IParseToken token) {
+      Null nil = (Null)token;
+      this.SetValue(nil.Name, null);      
+    }
+    private void SetValue(string name, object value) {
+       if (compositeStack.Count == 0) {
+        compositeStack.Push(new AccessibleObject(value, new Dictionary<string,DataMemberAccessor>()));
+      } else {
+        compositeStack.Peek().SetValue(name, value);
+      }      
+    }
   }
 
@@ -271,4 +396,117 @@
 
   }
-  
+
+  #region parsing tokens
+  public interface IParseToken { }
+  public class CompositeStart : IParseToken {
+    public string Name;
+    public Type Type;    
+    public int Id;
+    public CompositeStart(string name, Type type, int id) {
+      this.Name = name;
+      this.Type = type;
+      this.Id = id;      
+    }
+  }
+  public class CompositeEnd : IParseToken {
+    public string Name;
+    public Type Type;    
+    public int Id;
+    public CompositeEnd(string name, Type type, int id) {
+      this.Name = name;
+      this.Type = type;
+      this.Id = id;      
+    }
+  }
+  public class Primitive : IParseToken {
+    public string Name;
+    public Type Type;
+    public string SerializedValue;
+    public Primitive(string name, Type type, string serilaizedValue) {
+      this.Name = name;
+      this.Type = type;
+      this.SerializedValue = serilaizedValue;
+    }
+  }
+  public class Reference : IParseToken {
+    public string Name;
+    public int Id;
+    public Reference(string name, int id) {
+      this.Name = name;
+      this.Id = id;
+    }
+  }
+  public class Null : IParseToken {
+    public string Name;
+    public Null(string name) {
+      this.Name = name;
+    }
+  }
+  #endregion
+
+
+  public class XmlParser : IEnumerable<IParseToken> {
+
+    private XmlReader reader;
+    private delegate IEnumerator<IParseToken> Handler();
+    private Dictionary<string, Handler> handlers;
+
+    public XmlParser(StreamReader input) {
+      XmlReaderSettings settings = new XmlReaderSettings();
+      settings.ConformanceLevel = ConformanceLevel.Document;
+      settings.IgnoreWhitespace = true;
+      settings.IgnoreComments = true;
+      this.reader = XmlReader.Create(input, settings);
+      this.handlers = new Dictionary<string, Handler>();
+      this.handlers.Add("PRIMITIVE", new Handler(ParsePrimitive));
+      this.handlers.Add("COMPOSITE", new Handler(ParseComposite));
+      this.handlers.Add("REFERENCE", new Handler(ParseReference));
+      this.handlers.Add("NULL", new Handler(ParseNull));
+    }
+    public IEnumerator<IParseToken> GetEnumerator() {
+      while (this.reader.Read()) {
+        if (!reader.IsStartElement()) {          
+          break;
+        }
+        IEnumerator<IParseToken> iterator;
+        try {                      
+            iterator = handlers[reader.Name].Invoke();          
+        } catch (KeyNotFoundException) {          
+          throw new InvalidOperationException(String.Format(
+            "No handler for XML tag \"{0}\" installed",
+            reader.Name));
+        }
+        while (iterator.MoveNext()) {
+          yield return iterator.Current;
+        }
+      }      
+    }
+    private IEnumerator<IParseToken> ParsePrimitive() {
+      yield return new Primitive(
+        this.reader.GetAttribute("name"),
+        Type.GetType(this.reader.GetAttribute("type")),
+        this.reader.ReadString());      
+    }
+    private IEnumerator<IParseToken> ParseComposite() {
+      string name = this.reader.GetAttribute("name");
+      Type type = Type.GetType(this.reader.GetAttribute("type"));
+      int id = int.Parse(this.reader.GetAttribute("id"));
+      yield return new CompositeStart(name, type, id);        
+      IEnumerator<IParseToken> iterator = this.GetEnumerator();
+      while (iterator.MoveNext())
+        yield return iterator.Current;
+      yield return new CompositeEnd(name, type, id);      
+    }
+    private IEnumerator<IParseToken> ParseReference() {
+      yield return new Reference(
+        this.reader.GetAttribute("name"),
+        int.Parse(this.reader.GetAttribute("ref")));      
+    }
+    private IEnumerator<IParseToken> ParseNull() {
+      yield return new Null(this.reader.GetAttribute("name"));      
+    }        
+    IEnumerator IEnumerable.GetEnumerator() {
+      return this.GetEnumerator();
+    }    
+  }  
 }
Index: branches/New Persistence Exploration/Persistence/Persistence/Util.cs
===================================================================
--- branches/New Persistence Exploration/Persistence/Persistence/Util.cs	(revision 1274)
+++ branches/New Persistence Exploration/Persistence/Persistence/Util.cs	(revision 1274)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Reflection;
+
+namespace Persistence {
+  public class Util {
+    public static string AutoFormat(object o) {
+      return AutoFormat(o, false);
+    }
+    public static string AutoFormat(object o, bool recursive) {
+      string s = o as string;
+      if (s != null)
+        return s;
+      if (o == null) {
+        return "<null>";
+      }
+      StringBuilder sb = new StringBuilder();
+      sb.Append(o.GetType().Name);
+      sb.Append("(");
+      foreach (MemberInfo mInfo in o.GetType().GetMembers(
+        BindingFlags.Public |
+        BindingFlags.NonPublic |
+        BindingFlags.Instance)) {
+        if (mInfo.MemberType == MemberTypes.Field) {
+          sb.Append(mInfo.Name);
+          sb.Append("=");
+          if (recursive) {
+            sb.Append(AutoFormat(((FieldInfo)mInfo).GetValue(o)));
+          } else {
+            sb.Append(((FieldInfo)mInfo).GetValue(o));
+          }
+          sb.Append(", ");
+        }
+      }
+      sb.Remove(sb.Length - 2, 2);
+      sb.Append(")");
+      return sb.ToString();
+    }
+  }
+}
