Finalizing state to/from XML encoding and decoding
diff --git a/model/sync-state.cc b/model/sync-state.cc
index 268a45f..5e09655 100644
--- a/model/sync-state.cc
+++ b/model/sync-state.cc
@@ -21,8 +21,102 @@
  */
 
 #include "sync-state.h"
+#include "sync-diff-leaf.h"
+#include "sync-std-name-info.h"
+
 #include <boost/assert.hpp>
+#include <boost/foreach.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/lexical_cast.hpp>
+
+#define TIXML_USE_STL
+#include <tinyxml.h>
+
+using namespace std;
+using namespace boost;
+
+typedef error_info<struct tag_errmsg, string> info_str; 
 
 namespace Sync {
 
+#ifdef _DEBUG
+#define DEBUG_ENDL os << "\n";
+#else
+#define DEBUG_ENDL
+#endif
+
+std::ostream &
+operator << (std::ostream &os, const State &state)
+{
+  os << "<state>"; DEBUG_ENDL;
+  
+  BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ().get<ordered> ())
+    {
+      shared_ptr<const DiffLeaf> diffLeaf = dynamic_pointer_cast<const DiffLeaf> (leaf);
+      if (diffLeaf != 0)
+        {
+          os << "<item action=\"" << diffLeaf->getOperation () << "\">"; DEBUG_ENDL;
+        }
+      else
+        {
+          os << "<item>"; DEBUG_ENDL;
+        }
+      os << "<name>" << leaf->getInfo () << "</name>"; DEBUG_ENDL;
+      if (diffLeaf == 0 || (diffLeaf != 0 && diffLeaf->getOperation () == UPDATE))
+        {
+          os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
+        }
+      os << "</item>"; DEBUG_ENDL;
+    }
+  os << "</state>";
+}
+
+std::istream &
+operator >> (std::istream &in, State &state)
+{
+  TiXmlDocument doc;
+  in >> doc;
+
+  if (doc.RootElement() == 0)
+        BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("Empty XML"));
+  
+  for (TiXmlElement *iterator = doc.RootElement()->FirstChildElement ("item");
+       iterator != 0;
+       iterator = iterator->NextSiblingElement("item"))
+    {
+      TiXmlElement *name = iterator->FirstChildElement ("name");
+      if (name == 0 || name->GetText() == 0)
+        BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<name> element is missing"));
+        
+      NameInfoConstPtr info = StdNameInfo::FindOrCreate (name->GetText());
+      
+      if (iterator->Attribute("action") == 0 || strcmp(iterator->Attribute("action"), "update") == 0)
+        {
+          TiXmlElement *seq = iterator->FirstChildElement ("seq");
+          if (seq == 0)
+            BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seq> element is missing"));
+          
+          TiXmlElement *session = seq->FirstChildElement ("session");
+          TiXmlElement *seqno = seq->FirstChildElement ("seqno");
+
+          if (session == 0 || session->GetText() == 0)
+            BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<session> element is missing"));
+          if (seqno == 0 || seqno->GetText() == 0)
+            BOOST_THROW_EXCEPTION (SyncXmlDecodingFailure () << info_str ("<seqno> element is missing"));
+
+          state.update (info, SeqNo (
+                                     lexical_cast<uint32_t> (session->GetText()),
+                                     lexical_cast<uint32_t> (seqno->GetText())
+                                     ));
+        }
+      else
+        {
+          state.remove (info);
+        }
+    }
+
+  return in;
+}
+
 }