diff --git a/example/demo_xml.hpp b/example/demo_xml.hpp
new file mode 100644
index 0000000..408412a
--- /dev/null
+++ b/example/demo_xml.hpp
@@ -0,0 +1,284 @@
+#ifndef BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
+#define BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+//
+// demo_xml.hpp
+//
+// (C) Copyright 2002-4 Robert Ramey - http://www.rrsd.com .
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <string>
+#include <iomanip>
+#include <iostream>
+#include <fstream>
+
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/utility.hpp>
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/version.hpp>
+
+// This illustration models the bus system of a small city.
+// This includes, multiple bus stops,  bus routes and schedules.
+// There are different kinds of stops.  Bus stops in general will
+// will appear on multiple routes.  A schedule will include
+// muliple trips on the same route.
+
+/////////////////////////////////////////////////////////////
+// gps coordinate
+//
+// llustrates serialization for a simple type
+//
+class gps_position
+{
+    friend class boost::serialization::access;
+    friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
+
+    int degrees;
+    int minutes;
+    float seconds;
+
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int /* file_version */){
+        ar  & BOOST_SERIALIZATION_NVP(degrees)
+            & BOOST_SERIALIZATION_NVP(minutes)
+            & BOOST_SERIALIZATION_NVP(seconds);
+    }
+
+public:
+    // every serializable class needs a constructor
+    gps_position(){};
+    gps_position(int _d, int _m, float _s) : 
+        degrees(_d), minutes(_m), seconds(_s)
+    {}
+};
+
+std::ostream & operator<<(std::ostream &os, const gps_position &gp)
+{
+    return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
+}
+
+/////////////////////////////////////////////////////////////
+// One bus stop
+//
+// illustrates serialization of serializable members
+//
+
+class bus_stop
+{
+    friend class boost::serialization::access;
+    virtual std::string description() const = 0;
+    gps_position latitude;
+    gps_position longitude;
+
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int version)
+    {
+        ar & BOOST_SERIALIZATION_NVP(latitude);
+        ar & BOOST_SERIALIZATION_NVP(longitude);
+    }
+
+protected:
+    bus_stop(const gps_position & _lat, const gps_position & _long) :
+        latitude(_lat), longitude(_long)
+    {}
+public:
+    bus_stop(){}
+    friend std::ostream & operator<<(std::ostream &os, const bus_stop &gp);
+    virtual ~bus_stop(){}
+};
+
+BOOST_IS_ABSTRACT(bus_stop)
+
+std::ostream & operator<<(std::ostream &os, const bus_stop &bs)
+{
+    return os << bs.latitude << bs.longitude << ' ' << bs.description();
+}
+
+/////////////////////////////////////////////////////////////
+// Several kinds of bus stops
+//
+// illustrates serialization of derived types
+//
+class bus_stop_corner : public bus_stop
+{
+    friend class boost::serialization::access;
+    std::string street1;
+    std::string street2;
+    virtual std::string description() const
+    {
+        return street1 + " and " + street2;
+    }
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int version)
+    {
+        // save/load base class information
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop);
+        ar & BOOST_SERIALIZATION_NVP(street1);
+        ar & BOOST_SERIALIZATION_NVP(street2);
+    }
+public:
+    bus_stop_corner(){}
+    bus_stop_corner(const gps_position & _lat, const gps_position & _long,
+        const std::string & _s1, const std::string & _s2
+    ) :
+        bus_stop(_lat, _long), street1(_s1), street2(_s2)
+    {
+    }
+};
+
+class bus_stop_destination : public bus_stop
+{
+    friend class boost::serialization::access;
+    std::string name;
+    virtual std::string description() const
+    {
+        return name;
+    }
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int version)
+    {
+        ar  & BOOST_SERIALIZATION_BASE_OBJECT_NVP(bus_stop)
+            & BOOST_SERIALIZATION_NVP(name);
+    }
+public:
+    bus_stop_destination(){}
+    bus_stop_destination(
+        const gps_position & _lat, const gps_position & _long, const std::string & _name
+    ) :
+        bus_stop(_lat, _long), name(_name)
+    {
+    }
+};
+
+/////////////////////////////////////////////////////////////
+// a bus route is a collection of bus stops
+//
+// illustrates serialization of STL collection templates.
+//
+// illustrates serialzation of polymorphic pointer (bus stop *);
+//
+// illustrates storage and recovery of shared pointers is correct
+// and efficient.  That is objects pointed to by more than one
+// pointer are stored only once.  In such cases only one such
+// object is restored and pointers are restored to point to it
+//
+class bus_route
+{
+    friend class boost::serialization::access;
+    friend std::ostream & operator<<(std::ostream &os, const bus_route &br);
+    typedef bus_stop * bus_stop_pointer;
+    std::list<bus_stop_pointer> stops;
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int version)
+    {
+        // in this program, these classes are never serialized directly but rather
+        // through a pointer to the base class bus_stop. So we need a way to be
+        // sure that the archive contains information about these derived classes.
+        //ar.template register_type<bus_stop_corner>();
+        ar.register_type(static_cast<bus_stop_corner *>(NULL));
+        //ar.template register_type<bus_stop_destination>();
+        ar.register_type(static_cast<bus_stop_destination *>(NULL));
+        // serialization of stl collections is already defined
+        // in the header
+        ar & BOOST_SERIALIZATION_NVP(stops);
+    }
+public:
+    bus_route(){}
+    void append(bus_stop *_bs)
+    {
+        stops.insert(stops.end(), _bs);
+    }
+};
+std::ostream & operator<<(std::ostream &os, const bus_route &br)
+{
+    std::list<bus_stop *>::const_iterator it;
+    // note: we're displaying the pointer to permit verification
+    // that duplicated pointers are properly restored.
+    for(it = br.stops.begin(); it != br.stops.end(); it++){
+        os << '\n' << std::hex << "0x" << *it << std::dec << ' ' << **it;
+    }
+    return os;
+}
+
+/////////////////////////////////////////////////////////////
+// a bus schedule is a collection of routes each with a starting time
+//
+// Illustrates serialization of STL objects(pair) in a non-intrusive way.
+// See definition of operator<< <pair<F, S> >(ar, pair)
+// 
+// illustrates nesting of serializable classes
+//
+// illustrates use of version number to automatically grandfather older
+// versions of the same class.
+
+class bus_schedule
+{
+    friend class boost::serialization::access;
+    friend std::ostream & operator<<(std::ostream &os, const bus_schedule &bs);
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int version)
+    {
+        ar & BOOST_SERIALIZATION_NVP(schedule);
+    }
+    // note: this structure was made public. because the friend declarations
+    // didn't seem to work as expected.
+public:
+    struct trip_info
+    {
+        template<class Archive>
+        void serialize(Archive &ar, const unsigned int file_version)
+        {
+            // in versions 2 or later
+            if(file_version >= 2)
+                // read the drivers name
+                ar & BOOST_SERIALIZATION_NVP(driver);
+            // all versions have the follwing info
+            ar  & BOOST_SERIALIZATION_NVP(hour)
+                & BOOST_SERIALIZATION_NVP(minute);
+        }
+
+        // starting time
+        int hour;
+        int minute;
+        // only after system shipped was the driver's name added to the class
+        std::string driver;
+
+        trip_info(){}
+        trip_info(int _h, int _m, const std::string &_d) :
+            hour(_h), minute(_m), driver(_d)
+        {}
+        ~trip_info(){
+        }
+    };
+//  friend std::ostream & operator<<(std::ostream &os, const trip_info &ti);
+private:
+    std::list<std::pair<trip_info, bus_route *> > schedule;
+public:
+    void append(const std::string &_d, int _h, int _m, bus_route *_br)
+    {
+        schedule.insert(schedule.end(), std::make_pair(trip_info(_h, _m, _d), _br));
+    }
+    bus_schedule(){}
+};
+
+BOOST_CLASS_VERSION(bus_schedule::trip_info, 3)
+BOOST_CLASS_VERSION(bus_schedule, 2)
+
+std::ostream & operator<<(std::ostream &os, const bus_schedule::trip_info &ti)
+{
+    return os << '\n' << ti.hour << ':' << ti.minute << ' ' << ti.driver << ' ';
+}
+std::ostream & operator<<(std::ostream &os, const bus_schedule &bs)
+{
+    std::list<std::pair<bus_schedule::trip_info, bus_route *> >::const_iterator it;
+    for(it = bs.schedule.begin(); it != bs.schedule.end(); it++){
+        os << it->first << *(it->second);
+    }
+    return os;
+}
+
+#endif // BOOST_SERIALIZATION_EXAMPLE_DEMO_XML_HPP
